Entire project
This commit is contained in:
commit
d413e5ee0f
231 changed files with 49155 additions and 0 deletions
39
src/com/gnarly/engine/audio/ALManagement.java
Normal file
39
src/com/gnarly/engine/audio/ALManagement.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package com.gnarly.engine.audio;
|
||||
|
||||
import static org.lwjgl.openal.ALC10.alcCreateContext;
|
||||
import static org.lwjgl.openal.ALC10.alcMakeContextCurrent;
|
||||
import static org.lwjgl.openal.ALC10.alcOpenDevice;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.ALC;
|
||||
import org.lwjgl.openal.ALC10;
|
||||
import org.lwjgl.openal.ALCCapabilities;
|
||||
|
||||
public class ALManagement {
|
||||
|
||||
private long device, context;
|
||||
private ALCCapabilities deviceCaps;
|
||||
|
||||
public ALManagement() {
|
||||
device = alcOpenDevice((ByteBuffer) null);
|
||||
if (device == 0)
|
||||
throw new IllegalStateException("Failed to open the default device.");
|
||||
|
||||
deviceCaps = ALC.createCapabilities(device);
|
||||
|
||||
context = alcCreateContext(device, (IntBuffer) null);
|
||||
if (context == 0)
|
||||
throw new IllegalStateException("Failed to create an OpenAL context.");
|
||||
|
||||
alcMakeContextCurrent(context);
|
||||
AL.createCapabilities(deviceCaps);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
ALC10.alcDestroyContext(context);
|
||||
ALC10.alcCloseDevice(device);
|
||||
}
|
||||
}
|
38
src/com/gnarly/engine/audio/Sound.java
Normal file
38
src/com/gnarly/engine/audio/Sound.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
package com.gnarly.engine.audio;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
public class Sound {
|
||||
|
||||
private int buffer;
|
||||
private int sourceId;
|
||||
|
||||
public Sound(String path) {
|
||||
sourceId = AL10.alGenSources();
|
||||
buffer = AL10.alGenBuffers();
|
||||
WaveData waveData = WaveData.create(path);
|
||||
AL10.alBufferData(buffer, waveData.format, waveData.data, waveData.samplerate);
|
||||
AL10.alSourcei(sourceId, AL10.AL_BUFFER, buffer);
|
||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, 1);
|
||||
AL10.alSourcef(sourceId, AL10.AL_PITCH, 1);
|
||||
}
|
||||
|
||||
public void play(boolean loop) {
|
||||
AL10.alSourcei(sourceId, AL10.AL_LOOPING, loop ? 1 : 0);
|
||||
AL10.alSource3f(sourceId, AL10.AL_POSITION, 0, 0, 0);
|
||||
AL10.alSourcePlay(sourceId);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
AL10.alSourceStop(sourceId);
|
||||
}
|
||||
|
||||
public void setVolume(float volume) {
|
||||
AL10.alSourcef(sourceId, AL10.AL_GAIN, volume);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
AL10.alDeleteBuffers(buffer);
|
||||
AL10.alDeleteSources(sourceId);
|
||||
}
|
||||
}
|
88
src/com/gnarly/engine/audio/WaveData.java
Normal file
88
src/com/gnarly/engine/audio/WaveData.java
Normal file
|
@ -0,0 +1,88 @@
|
|||
package com.gnarly.engine.audio;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
public class WaveData {
|
||||
|
||||
final int format;
|
||||
final int samplerate;
|
||||
final int totalBytes;
|
||||
final int bytesPerFrame;
|
||||
final ByteBuffer data;
|
||||
|
||||
private final AudioInputStream audioStream;
|
||||
private final byte[] dataArray;
|
||||
|
||||
private WaveData(AudioInputStream stream) {
|
||||
this.audioStream = stream;
|
||||
AudioFormat audioFormat = stream.getFormat();
|
||||
format = getOpenAlFormat(audioFormat.getChannels(), audioFormat.getSampleSizeInBits());
|
||||
this.samplerate = (int) audioFormat.getSampleRate();
|
||||
this.bytesPerFrame = audioFormat.getFrameSize();
|
||||
this.totalBytes = (int) (stream.getFrameLength() * bytesPerFrame);
|
||||
this.data = BufferUtils.createByteBuffer(totalBytes);
|
||||
this.dataArray = new byte[totalBytes];
|
||||
loadData();
|
||||
}
|
||||
|
||||
protected void dispose() {
|
||||
try {
|
||||
audioStream.close();
|
||||
data.clear();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private ByteBuffer loadData() {
|
||||
try {
|
||||
int bytesRead = audioStream.read(dataArray, 0, totalBytes);
|
||||
data.clear();
|
||||
data.put(dataArray, 0, bytesRead);
|
||||
data.flip();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Couldn't read bytes from audio stream!");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static WaveData create(String file) {
|
||||
WaveData wavStream = null;
|
||||
try {
|
||||
InputStream stream = new FileInputStream(new File(file));
|
||||
InputStream bufferedInput = new BufferedInputStream(stream);
|
||||
AudioInputStream audioStream = null;
|
||||
audioStream = AudioSystem.getAudioInputStream(bufferedInput);
|
||||
wavStream = new WaveData(audioStream);
|
||||
} catch (UnsupportedAudioFileException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return wavStream;
|
||||
}
|
||||
|
||||
|
||||
private static int getOpenAlFormat(int channels, int bitsPerSample) {
|
||||
if (channels == 1) {
|
||||
return bitsPerSample == 8 ? AL10.AL_FORMAT_MONO8 : AL10.AL_FORMAT_MONO16;
|
||||
} else {
|
||||
return bitsPerSample == 8 ? AL10.AL_FORMAT_STEREO8 : AL10.AL_FORMAT_STEREO16;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
100
src/com/gnarly/engine/display/Camera.java
Normal file
100
src/com/gnarly/engine/display/Camera.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package com.gnarly.engine.display;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public class Camera {
|
||||
|
||||
private Matrix4f projection, projView;
|
||||
|
||||
private float width, height;
|
||||
private Vector3f position;
|
||||
private float rotation;
|
||||
|
||||
public Camera(float width, float height) {
|
||||
setDims(width, height);
|
||||
position = new Vector3f();
|
||||
rotation = 0;
|
||||
projView = new Matrix4f();
|
||||
}
|
||||
|
||||
public void setDims(float width, float height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
projection = new Matrix4f().setOrtho(0, width, height, 0, 0, 1);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
projection.translate(position.negate(new Vector3f()), projView).rotateZ(-rotation);
|
||||
}
|
||||
|
||||
public Matrix4f getProjection() {
|
||||
return new Matrix4f(projection);
|
||||
}
|
||||
|
||||
public Matrix4f getMatrix() {
|
||||
return new Matrix4f(projView);
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return position.x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return position.y;
|
||||
}
|
||||
|
||||
public Vector3f getPosition() {
|
||||
return new Vector3f(position);
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
position.x = x;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
position.y = y;
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y) {
|
||||
position.set(x, y, position.z);
|
||||
}
|
||||
|
||||
public void setPosition(Vector3f position) {
|
||||
this.position.x = position.x;
|
||||
this.position.y = position.y;
|
||||
}
|
||||
|
||||
public void setCenter(float x, float y) {
|
||||
position.set(x - width / 2, y - height / 2, position.z);
|
||||
}
|
||||
|
||||
public void setCenter(Vector3f position) {
|
||||
this.position.x = position.x - width / 2;
|
||||
this.position.y = position.y - height / 2;
|
||||
}
|
||||
|
||||
public void translate(float x, float y, float z) {
|
||||
position.add(x, y, z);
|
||||
}
|
||||
|
||||
public void translate(Vector3f transform) {
|
||||
position.add(transform);
|
||||
}
|
||||
|
||||
public void setRotation(float angle) {
|
||||
rotation = angle;
|
||||
}
|
||||
|
||||
public void rotate(float angle) {
|
||||
rotation += angle;
|
||||
}
|
||||
}
|
119
src/com/gnarly/engine/display/Framebuffer.java
Normal file
119
src/com/gnarly/engine/display/Framebuffer.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
package com.gnarly.engine.display;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_CLAMP;
|
||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_COMPONENT;
|
||||
import static org.lwjgl.opengl.GL11.GL_NEAREST;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL11.glClear;
|
||||
import static org.lwjgl.opengl.GL11.glClearColor;
|
||||
import static org.lwjgl.opengl.GL11.glDrawBuffer;
|
||||
import static org.lwjgl.opengl.GL11.glGenTextures;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameterf;
|
||||
import static org.lwjgl.opengl.GL11.glViewport;
|
||||
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT0;
|
||||
import static org.lwjgl.opengl.GL30.GL_DEPTH_ATTACHMENT;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
|
||||
import static org.lwjgl.opengl.GL30.glBindRenderbuffer;
|
||||
import static org.lwjgl.opengl.GL30.glDeleteFramebuffers;
|
||||
import static org.lwjgl.opengl.GL30.glDeleteRenderbuffers;
|
||||
import static org.lwjgl.opengl.GL30.glFramebufferRenderbuffer;
|
||||
import static org.lwjgl.opengl.GL30.glGenFramebuffers;
|
||||
import static org.lwjgl.opengl.GL30.glGenRenderbuffers;
|
||||
import static org.lwjgl.opengl.GL30.glRenderbufferStorage;
|
||||
import static org.lwjgl.opengl.GL32.glFramebufferTexture;
|
||||
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
|
||||
public class Framebuffer {
|
||||
|
||||
int fbo, rbo, width, height;
|
||||
int colorBuf, depthTex;
|
||||
float r, g, b, a;
|
||||
|
||||
Framebuffer(int width, int height, float r, float g, float b, float a) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
|
||||
fbo = glGenFramebuffers();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
rbo = 0;
|
||||
colorBuf = 0;
|
||||
depthTex = 0;
|
||||
}
|
||||
|
||||
Framebuffer addColorAttachment(Texture texture) {
|
||||
if (colorBuf == 0) {
|
||||
int id = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
texture = new Texture(id, width, height);
|
||||
colorBuf = 1;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Framebuffer addDepthTextureAttachment(Texture texture) {
|
||||
if (depthTex == 0) {
|
||||
int id = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, id, 0);
|
||||
texture = new Texture(id, width, height);
|
||||
depthTex = 1;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Framebuffer addDepthBufferAttachment() {
|
||||
if (rbo == 0) {
|
||||
rbo = glGenRenderbuffers();
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void bind() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
void unbind(Window window) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, window.getWidth(), window.getHeight());
|
||||
window.activateClearColor();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
if (rbo != 0)
|
||||
glDeleteRenderbuffers(rbo);
|
||||
glDeleteFramebuffers(fbo);
|
||||
}
|
||||
}
|
250
src/com/gnarly/engine/display/Window.java
Normal file
250
src/com/gnarly/engine/display/Window.java
Normal file
|
@ -0,0 +1,250 @@
|
|||
package com.gnarly.engine.display;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_DECORATED;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_LAST;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_MAXIMIZED;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LAST;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_PRESS;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_RELEASE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_REPEAT;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_SAMPLES;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
|
||||
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
|
||||
import static org.lwjgl.glfw.GLFW.glfwGetCursorPos;
|
||||
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
|
||||
import static org.lwjgl.glfw.GLFW.glfwGetVideoMode;
|
||||
import static org.lwjgl.glfw.GLFW.glfwGetWindowSize;
|
||||
import static org.lwjgl.glfw.GLFW.glfwInit;
|
||||
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
|
||||
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSetMouseButtonCallback;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSetWindowSizeCallback;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
|
||||
import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
|
||||
import static org.lwjgl.glfw.GLFW.glfwTerminate;
|
||||
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
|
||||
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
|
||||
import static org.lwjgl.opengl.GL.createCapabilities;
|
||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TRUE;
|
||||
import static org.lwjgl.opengl.GL11.glBlendFunc;
|
||||
import static org.lwjgl.opengl.GL11.glClear;
|
||||
import static org.lwjgl.opengl.GL11.glClearColor;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
import static org.lwjgl.opengl.GL11.glViewport;
|
||||
import static org.lwjgl.opengl.GL13.GL_MULTISAMPLE;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
import org.lwjgl.glfw.GLFWVidMode;
|
||||
|
||||
public class Window {
|
||||
|
||||
public static String resolution;
|
||||
|
||||
public static int
|
||||
SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT;
|
||||
|
||||
public static final int
|
||||
BUTTON_RELEASED = 0,
|
||||
BUTTON_UNPRESSED = 1,
|
||||
BUTTON_PRESSED = 2,
|
||||
BUTTON_HELD = 3,
|
||||
BUTTON_REPEAT = 4;
|
||||
|
||||
public static float SCALE;
|
||||
|
||||
private long window;
|
||||
private int width, height;
|
||||
private boolean resized;
|
||||
|
||||
private int[] mouseButtons = new int[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||
private int[] keys = new int[GLFW_KEY_LAST + 1];
|
||||
|
||||
public Window(String title, boolean vSync) {
|
||||
init(0, 0, title, vSync, false, false, false);
|
||||
}
|
||||
|
||||
public Window(String title, boolean vSync, boolean resizable, boolean decorated) {
|
||||
init(800, 500, title, vSync, resizable, decorated, true);
|
||||
}
|
||||
|
||||
public Window(int width, int height, String title, boolean vSync, boolean resizable, boolean decorated) {
|
||||
init(width, height, title, vSync, resizable, decorated, false);
|
||||
}
|
||||
|
||||
public void init(int lwidth, int lheight, String title, boolean vSync, boolean resizable, boolean decorated, boolean maximized) {
|
||||
glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
|
||||
|
||||
for (int i = 0; i < mouseButtons.length; i++)
|
||||
mouseButtons[i] = 0;
|
||||
|
||||
if(!glfwInit()) {
|
||||
System.err.println("GLFW failed to initialize!");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
|
||||
glfwWindowHint(GLFW_SAMPLES, 8);
|
||||
glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_DECORATED, decorated ? GLFW_TRUE : GLFW_FALSE);
|
||||
glfwWindowHint(GLFW_MAXIMIZED, maximized ? GLFW_TRUE : GLFW_FALSE);
|
||||
|
||||
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
SCREEN_WIDTH = vidMode.width();
|
||||
SCREEN_HEIGHT = vidMode.height();
|
||||
SCALE = SCREEN_HEIGHT / 1080f;
|
||||
if(lwidth == 0 || lheight == 0) {
|
||||
width = vidMode.width();
|
||||
height = vidMode.height();
|
||||
window = glfwCreateWindow(width, height, title, glfwGetPrimaryMonitor(), 0);
|
||||
}
|
||||
else {
|
||||
this.width = lwidth;
|
||||
this.height = lheight;
|
||||
window = glfwCreateWindow(width, height, title, 0, 0);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
createCapabilities();
|
||||
|
||||
glfwSwapInterval(vSync ? 1 : 0);
|
||||
|
||||
glfwSetWindowSizeCallback(window, (long window, int w, int h) -> {
|
||||
width = w;
|
||||
height = h;
|
||||
resized = true;
|
||||
glViewport(0, 0, width, height);
|
||||
});
|
||||
|
||||
glfwSetMouseButtonCallback(window, (long window, int button, int action, int mods) -> {
|
||||
if (action == GLFW_RELEASE)
|
||||
mouseButtons[button] = BUTTON_RELEASED;
|
||||
if (action == GLFW_PRESS)
|
||||
mouseButtons[button] = BUTTON_PRESSED;
|
||||
if (action == GLFW_REPEAT)
|
||||
mouseButtons[button] = BUTTON_REPEAT;
|
||||
});
|
||||
|
||||
glfwSetKeyCallback(window, (long window, int key, int scancode, int action, int mods) -> {
|
||||
if (key != -1) {
|
||||
if (action == GLFW_RELEASE)
|
||||
keys[key] = BUTTON_RELEASED;
|
||||
if (action == GLFW_PRESS)
|
||||
keys[key] = BUTTON_PRESSED;
|
||||
if (action == GLFW_REPEAT)
|
||||
keys[key] = BUTTON_REPEAT;
|
||||
}
|
||||
});
|
||||
|
||||
activateClearColor();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
int[] awidth = new int[1], aheight = new int[1];
|
||||
glfwGetWindowSize(window, awidth, aheight);
|
||||
width = awidth[0];
|
||||
height = aheight[0];
|
||||
|
||||
if(SCREEN_HEIGHT > 2160)
|
||||
resolution = "8k";
|
||||
else if(SCREEN_HEIGHT > 1440)
|
||||
resolution = "4k";
|
||||
else if(SCREEN_HEIGHT > 1080)
|
||||
resolution = "1440p";
|
||||
else if(SCREEN_HEIGHT > 720)
|
||||
resolution = "1080p";
|
||||
else
|
||||
resolution = "720p";
|
||||
}
|
||||
|
||||
public void update() {
|
||||
for (int i = 0; i < mouseButtons.length; i++)
|
||||
if (mouseButtons[i] == BUTTON_RELEASED || mouseButtons[i] == BUTTON_PRESSED)
|
||||
++mouseButtons[i];
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
if (keys[i] == BUTTON_RELEASED || keys[i] == BUTTON_PRESSED)
|
||||
++keys[i];
|
||||
resized = false;
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
public void activateClearColor() {
|
||||
glClearColor(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
public void swap() {
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
public static void terminate() {
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
public boolean shouldClose() {
|
||||
return glfwWindowShouldClose(window);
|
||||
}
|
||||
|
||||
public int keyPressed(int keyCode) {
|
||||
return keys[keyCode];
|
||||
}
|
||||
|
||||
public Vector3f getMouseCoords(Camera camera) {
|
||||
double[] x = new double[1], y = new double[1];
|
||||
glfwGetCursorPos(window, x, y);
|
||||
Vector3f ret = new Vector3f((float) x[0], (float) y[0], 0);
|
||||
return ret.mul(camera.getWidth() / this.width, camera.getHeight() / this.height, 1);
|
||||
}
|
||||
|
||||
public int mousePressed(int button) {
|
||||
return mouseButtons[button];
|
||||
}
|
||||
|
||||
public boolean wasResized() {
|
||||
return resized;
|
||||
}
|
||||
}
|
121
src/com/gnarly/engine/model/Circle.java
Normal file
121
src/com/gnarly/engine/model/Circle.java
Normal file
|
@ -0,0 +1,121 @@
|
|||
package com.gnarly.engine.model;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.shaders.Shader;
|
||||
import com.gnarly.engine.shaders.Shader2c;
|
||||
|
||||
public class Circle {
|
||||
|
||||
private static Vao vao;
|
||||
|
||||
private Camera camera;
|
||||
private Shader2c shader;
|
||||
private Vector3f position;
|
||||
private float radius;
|
||||
private float r, g, b, a;
|
||||
|
||||
public Circle(Camera camera, float x, float y, float z, float radius) {
|
||||
this.camera = camera;
|
||||
position = new Vector3f(x, y, z);
|
||||
this.radius = radius;
|
||||
shader = Shader.SHADER2C;
|
||||
r = 1;
|
||||
g = 0;
|
||||
b = 0;
|
||||
a = 1;
|
||||
if(vao == null)
|
||||
initVao();
|
||||
}
|
||||
|
||||
private void initVao() {
|
||||
final int NUM_POINTS = 30;
|
||||
float[] cVertices = new float[NUM_POINTS * 3];
|
||||
int[] cIndices = new int[(NUM_POINTS - 2) * 3];
|
||||
for (int i = 0; i < cVertices.length; i += 3) {
|
||||
double angle = Math.PI * 2 * i / (NUM_POINTS * 3);
|
||||
cVertices[i ] = (float) Math.cos(angle);
|
||||
cVertices[i + 1] = (float) Math.sin(angle);
|
||||
cVertices[i + 2] = 0;
|
||||
}
|
||||
for (int i = 0; i < cIndices.length; i += 3) {
|
||||
cIndices[i ] = 0;
|
||||
cIndices[i + 1] = i / 3 + 1;
|
||||
cIndices[i + 2] = i / 3 + 2;
|
||||
}
|
||||
vao = new Vao(cVertices, cIndices);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
shader.enable();
|
||||
shader.setMVP(camera.getMatrix().translate(position).scale(radius));
|
||||
shader.setColor(r, g, b, a);
|
||||
vao.render();
|
||||
}
|
||||
|
||||
public Vector3f getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
position.x = x;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
position.y = y;
|
||||
}
|
||||
|
||||
public void setZ(float z) {
|
||||
position.z = z;
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y) {
|
||||
position.x = x;
|
||||
position.y = y;
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y, float z) {
|
||||
position.x = x;
|
||||
position.y = y;
|
||||
position.z = z;
|
||||
}
|
||||
|
||||
public void setPosition(Vector3f position) {
|
||||
this.position.set(position);
|
||||
}
|
||||
|
||||
public void translate(float x, float y) {
|
||||
position.x += x;
|
||||
position.y += y;
|
||||
}
|
||||
|
||||
public void translate(float x, float y, float z) {
|
||||
position.x += x;
|
||||
position.y += y;
|
||||
position.z += z;
|
||||
}
|
||||
|
||||
public void translate(Vector3f position) {
|
||||
this.position.add(position);
|
||||
}
|
||||
|
||||
public void setRadius(float radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public void setDiameter(float diameter) {
|
||||
this.radius = diameter / 2;
|
||||
}
|
||||
|
||||
public void setColor(float r, float g, float b, float a) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public boolean contains(Vector3f vector) {
|
||||
return (position.sub(vector, new Vector3f()).lengthSquared() < radius * radius);
|
||||
}
|
||||
}
|
50
src/com/gnarly/engine/model/ColRect.java
Normal file
50
src/com/gnarly/engine/model/ColRect.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
package com.gnarly.engine.model;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.shaders.Shader;
|
||||
import com.gnarly.engine.shaders.Shader2c;
|
||||
|
||||
public class ColRect extends Rect {
|
||||
|
||||
private Shader2c shader;
|
||||
|
||||
protected float r, g, b, a;
|
||||
|
||||
public ColRect(Camera camera, float x, float y, float z, float width, float height, float r, float g, float b, float a, boolean gui) {
|
||||
super(camera, x, y, z, width, height, 0, gui);
|
||||
shader = Shader.SHADER2C;
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
shader.enable();
|
||||
shader.setColor(r, g, b, a);
|
||||
Matrix4f cmat = gui ? camera.getProjection() : camera.getMatrix();
|
||||
shader.setMVP(cmat.translate(position.add(width * scale / 2, height * scale / 2, 0, new Vector3f())).rotateZ(rotation * 3.1415927f / 180).scale(width * scale, height * scale, 1).translate(-0.5f, -0.5f, 0));
|
||||
vao.render();
|
||||
shader.disable();
|
||||
}
|
||||
|
||||
public void setColor(float r, float g, float b) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public void setColor(float r, float g, float b, float a) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
public void setAlpha(float alpha) {
|
||||
a = alpha;
|
||||
}
|
||||
}
|
118
src/com/gnarly/engine/model/Line.java
Normal file
118
src/com/gnarly/engine/model/Line.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
package com.gnarly.engine.model;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.shaders.Shader;
|
||||
import com.gnarly.engine.shaders.Shader2c;
|
||||
|
||||
public class Line {
|
||||
|
||||
private static Vao cap, rect;
|
||||
|
||||
private Camera camera;
|
||||
private Shader2c shader;
|
||||
|
||||
private Vector3f position;
|
||||
private float angle, length, thickness;
|
||||
private float r, g, b, a;
|
||||
|
||||
public Line(Camera camera, float x1, float y1, float x2, float y2, float depth, float thickness) {
|
||||
this.camera = camera;
|
||||
shader = Shader.SHADER2C;
|
||||
if(cap == null)
|
||||
initVaos();
|
||||
this.thickness = thickness;
|
||||
position = new Vector3f(x1, y1, depth);
|
||||
setPoints(x1, y1, x2, y2);
|
||||
r = 1;
|
||||
g = 1;
|
||||
b = 1;
|
||||
a = 1;
|
||||
}
|
||||
|
||||
private void initVaos() {
|
||||
float[] rVertices = {
|
||||
0, 0.5f, 0,
|
||||
0, -0.5f, 0,
|
||||
1, -0.5f, 0,
|
||||
1, 0.5f, 0
|
||||
};
|
||||
int rIndices[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
rect = new Vao(rVertices, rIndices);
|
||||
final int NUM_POINTS = 10;
|
||||
float[] cVertices = new float[NUM_POINTS * 3];
|
||||
int[] cIndices = new int[(NUM_POINTS - 2) * 3];
|
||||
for (int i = 0; i < cVertices.length; i += 3) {
|
||||
double angle = Math.PI * i / (NUM_POINTS * 3 - 3) + Math.PI / 2;
|
||||
cVertices[i ] = (float) Math.cos(angle) / 2;
|
||||
cVertices[i + 1] = (float) Math.sin(angle) / 2;
|
||||
cVertices[i + 2] = 0;
|
||||
}
|
||||
for (int i = 0; i < cIndices.length; i += 3) {
|
||||
cIndices[i ] = 0;
|
||||
cIndices[i + 1] = i / 3 + 1;
|
||||
cIndices[i + 2] = i / 3 + 2;
|
||||
}
|
||||
cap = new Vao(cVertices, cIndices);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
shader.enable();
|
||||
shader.setColor(r, g, b, a);
|
||||
shader.setMVP(camera.getMatrix().translate(position).rotateZ(angle).scale(thickness));
|
||||
cap.render();
|
||||
shader.setMVP(camera.getMatrix().translate(position).rotateZ(angle).scale(length, thickness, 1));
|
||||
rect.render();
|
||||
shader.setMVP(camera.getMatrix().translate(position.add((float) (Math.cos(angle) * length), (float) (-Math.sin(Math.PI + angle) * length), 0, new Vector3f())).rotateZ((float) Math.PI).rotateZ(angle).scale(thickness));
|
||||
cap.render();
|
||||
shader.disable();
|
||||
}
|
||||
|
||||
public void setAngle(float x, float y, float angle, float length) {
|
||||
position.x = x;
|
||||
position.y = y;
|
||||
this.angle = angle;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public void setPoints(float x1, float y1, float x2, float y2) {
|
||||
float xl = x2 - x1;
|
||||
float yl = y2 - y1;
|
||||
length = (float) Math.sqrt(xl * xl + yl * yl);
|
||||
if(x1 != x2) {
|
||||
angle = (float) Math.atan(yl / xl);
|
||||
if(xl < 0)
|
||||
angle += Math.PI;
|
||||
setAngle(x1, y1, angle, length);
|
||||
}
|
||||
else if(y1 > y2)
|
||||
setAngle(x1, y1, (float) Math.PI * 1.5f, length);
|
||||
else if(y1 < y2)
|
||||
setAngle(x1, y1, (float) Math.PI * 0.5f, length);
|
||||
else
|
||||
setAngle(x1, y1, 0, 0);
|
||||
}
|
||||
|
||||
public void setPoints(Vector3f p1, Vector3f p2) {
|
||||
setPoints(p1.x, p1.y, p2.x, p2.y);
|
||||
}
|
||||
|
||||
public void setThickness(float thickness) {
|
||||
this.thickness = thickness;
|
||||
}
|
||||
|
||||
public void setDepth(float z) {
|
||||
position.z = z;
|
||||
}
|
||||
|
||||
public void setColor(float r, float g, float b, float a) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
}
|
||||
}
|
130
src/com/gnarly/engine/model/Rect.java
Normal file
130
src/com/gnarly/engine/model/Rect.java
Normal file
|
@ -0,0 +1,130 @@
|
|||
package com.gnarly.engine.model;
|
||||
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
|
||||
public class Rect {
|
||||
|
||||
protected static Vao vao;
|
||||
|
||||
protected Camera camera;
|
||||
|
||||
protected float width, height;
|
||||
protected Vector3f position;
|
||||
protected float rotation, scale;
|
||||
protected boolean gui;
|
||||
|
||||
protected Rect(Camera camera, float x, float y, float z, float width, float height, float rotation, boolean gui) {
|
||||
this.camera = camera;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
position = new Vector3f(x, y, z);
|
||||
scale = 1;
|
||||
this.rotation = rotation;
|
||||
this.gui = gui;
|
||||
if(vao == null) {
|
||||
float vertices[] = {
|
||||
1, 0, 0, // Top left
|
||||
1, 1, 0, // Bottom left
|
||||
0, 1, 0, // Bottom right
|
||||
0, 0, 0 // Top right
|
||||
};
|
||||
int indices[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
float[] texCoords = {
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
0, 0
|
||||
};
|
||||
vao = new Vao(vertices, indices);
|
||||
vao.addAttrib(texCoords, 2);
|
||||
}
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return position.x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return position.y;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
position.x = x;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
position.y = y;
|
||||
}
|
||||
|
||||
public void set(float x, float y, float width, float height) {
|
||||
position.x = x;
|
||||
position.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setWidth(float width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public void setHeight(float height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y) {
|
||||
position.set(x, y, position.z);
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y, float z) {
|
||||
position.set(x, y, z);
|
||||
}
|
||||
|
||||
public void setPosition(Vector3f position) {
|
||||
this.position.x = position.x;
|
||||
this.position.y = position.y;
|
||||
this.position.z = position.z;
|
||||
}
|
||||
|
||||
public void setPosition(Vector2f position) {
|
||||
this.position.x = position.x;
|
||||
this.position.y = position.y;
|
||||
}
|
||||
|
||||
public void translate(Vector3f vector) {
|
||||
position.add(vector);
|
||||
}
|
||||
|
||||
public void translate(float x, float y, float z) {
|
||||
position.add(x, y, z);
|
||||
}
|
||||
|
||||
public void setRotation(float angle) {
|
||||
rotation = angle;
|
||||
}
|
||||
|
||||
public void rotate(float angle) {
|
||||
rotation += angle;
|
||||
}
|
||||
|
||||
public void setScale(float scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public void setAngle(float angle) {
|
||||
this.rotation = angle;
|
||||
}
|
||||
}
|
69
src/com/gnarly/engine/model/TexRect.java
Normal file
69
src/com/gnarly/engine/model/TexRect.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
package com.gnarly.engine.model;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.shaders.Shader;
|
||||
import com.gnarly.engine.shaders.Shader2t;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
|
||||
public class TexRect extends Rect {
|
||||
|
||||
private Texture texture;
|
||||
private Shader2t shader = Shader.SHADER2T;
|
||||
protected float direction = 1;
|
||||
private float alpha = 1;
|
||||
private float r;
|
||||
private float g;
|
||||
private float b;
|
||||
private float a;
|
||||
private float amount = 1;
|
||||
|
||||
public TexRect(Camera camera, String path, float x, float y, float z, float width, float height, float rotation, boolean gui) {
|
||||
super(camera, x, y, z, width, height, rotation, gui);
|
||||
texture = new Texture(path);
|
||||
}
|
||||
|
||||
public TexRect(Camera camera, Texture texture, float x, float y, float z, float width, float height, float rotation, boolean gui) {
|
||||
super(camera, x, y, z, width, height, rotation, gui);
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
texture.bind();
|
||||
shader.enable();
|
||||
Matrix4f cmat = gui ? camera.getProjection() : camera.getMatrix();
|
||||
shader.setMVP(cmat.translate(position.add(width * scale / 2, height * scale / 2, 0, new Vector3f())).rotateZ(rotation).scale(width * scale * direction, height * scale, 1).translate(-0.5f, -0.5f, 0));
|
||||
shader.setAlpha(alpha);
|
||||
shader.setMixColor(r, g, b, a, amount);
|
||||
vao.render();
|
||||
shader.disable();
|
||||
texture.unbind();
|
||||
}
|
||||
|
||||
public void setCenter(float x, float y) {
|
||||
position.x = x - width / 2;
|
||||
position.y = y - height / 2;
|
||||
}
|
||||
|
||||
public void setTexture(Texture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public void setMix(float r, float g, float b, float a, float amount) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
this.amount = 1 - amount;
|
||||
}
|
||||
|
||||
public void setAlpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
public float getAlpha() {
|
||||
return alpha;
|
||||
}
|
||||
}
|
63
src/com/gnarly/engine/model/Vao.java
Normal file
63
src/com/gnarly/engine/model/Vao.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
package com.gnarly.engine.model;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
|
||||
import static org.lwjgl.opengl.GL11.glDrawElements;
|
||||
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
|
||||
import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER;
|
||||
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
|
||||
import static org.lwjgl.opengl.GL15.glBindBuffer;
|
||||
import static org.lwjgl.opengl.GL15.glBufferData;
|
||||
import static org.lwjgl.opengl.GL15.glDeleteBuffers;
|
||||
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
||||
import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray;
|
||||
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
||||
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||
import static org.lwjgl.opengl.GL30.glDeleteVertexArrays;
|
||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||
|
||||
public class Vao {
|
||||
|
||||
private int numAttribs = 0;
|
||||
|
||||
private int vao, ibo, count;
|
||||
|
||||
private int[] vbos = new int[15];
|
||||
|
||||
public Vao(float[] vertices, int[] indices) {
|
||||
vao = glGenVertexArrays();
|
||||
glBindVertexArray(vao);
|
||||
addAttrib(vertices, 3);
|
||||
ibo = glGenBuffers();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
|
||||
count = indices.length;
|
||||
}
|
||||
|
||||
public void addAttrib(float[] data, int size) {
|
||||
int vbo = glGenBuffers();
|
||||
vbos[numAttribs] = vbo;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(numAttribs, size, GL_FLOAT, false, 0, 0);
|
||||
++numAttribs;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
glBindVertexArray(vao);
|
||||
for(int i = 0; i < numAttribs; ++i)
|
||||
glEnableVertexAttribArray(i);
|
||||
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
|
||||
for(int i = 0; i < numAttribs; ++i)
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
for(int vbo : vbos)
|
||||
glDeleteBuffers(vbo);
|
||||
glDeleteBuffers(ibo);
|
||||
glDeleteVertexArrays(vao);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.gnarly.engine.properties;
|
||||
|
||||
public class ImproperFormattingException extends RuntimeException {
|
||||
|
||||
public ImproperFormattingException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
104
src/com/gnarly/engine/properties/Properties.java
Normal file
104
src/com/gnarly/engine/properties/Properties.java
Normal file
|
@ -0,0 +1,104 @@
|
|||
package com.gnarly.engine.properties;
|
||||
|
||||
public class Properties {
|
||||
|
||||
private String name;
|
||||
private PropNode head, cur;
|
||||
|
||||
public Properties(String name) {
|
||||
this.name = new String(name);
|
||||
}
|
||||
|
||||
public void add(PropNode node) {
|
||||
if(head == null) {
|
||||
head = node;
|
||||
cur = node;
|
||||
}
|
||||
else {
|
||||
cur.next = node;
|
||||
cur = cur.next;
|
||||
}
|
||||
}
|
||||
|
||||
private PropNode get(String key) throws UndeclaredPropertyException {
|
||||
String[] keys = key.split("\\.");
|
||||
PropNode mobile = head;
|
||||
while (mobile != null) {
|
||||
if(mobile.key.equals(keys[0])) {
|
||||
if(keys.length > 1 && mobile instanceof BlockNode)
|
||||
return ((BlockNode) mobile).data.get(key.substring(keys[0].length() + 1));
|
||||
else
|
||||
return mobile;
|
||||
}
|
||||
mobile = mobile.next;
|
||||
}
|
||||
throw new UndeclaredPropertyException("Property '" + key + "' in properties '" + name + "' was not found!");
|
||||
}
|
||||
|
||||
public String getAsString(String key) throws UndeclaredPropertyException {
|
||||
return ((StringNode) get(key)).data;
|
||||
}
|
||||
|
||||
public int getAsInt(String key) throws UndeclaredPropertyException {
|
||||
return ((IntNode) get(key)).data;
|
||||
}
|
||||
|
||||
public int[] getAsIntArray(String key) throws UndeclaredPropertyException {
|
||||
PropNode node = get(key);
|
||||
if(node instanceof IntNode)
|
||||
return new int[] { ((IntNode) node).data };
|
||||
return ((IntArrayNode) get(key)).data;
|
||||
}
|
||||
|
||||
public double getAsDouble(String key) throws UndeclaredPropertyException {
|
||||
PropNode node = get(key);
|
||||
if(node instanceof IntNode)
|
||||
return (double) ((IntNode) node).data;
|
||||
return ((DoubleNode) get(key)).data;
|
||||
}
|
||||
|
||||
public double[] getAsDoubleArray(String key) throws UndeclaredPropertyException {
|
||||
PropNode node = get(key);
|
||||
if(node instanceof DoubleNode)
|
||||
return new double[] { ((DoubleNode) node).data };
|
||||
if(node instanceof IntNode)
|
||||
return new double[] { ((IntNode) node).data };
|
||||
if(node instanceof IntArrayNode) {
|
||||
int[] ints = getAsIntArray(key);
|
||||
double[] ret = new double[ints.length];
|
||||
for (int i = 0; i < ints.length; ++i)
|
||||
ret[i] = ints[i];
|
||||
return ret;
|
||||
}
|
||||
return ((DoubleArrayNode) get(key)).data;
|
||||
}
|
||||
|
||||
public static class PropNode {
|
||||
public String key;
|
||||
public PropNode next;
|
||||
}
|
||||
|
||||
public static class BlockNode extends PropNode {
|
||||
public Properties data;
|
||||
}
|
||||
|
||||
public static class StringNode extends PropNode {
|
||||
public String data;
|
||||
}
|
||||
|
||||
public static class IntNode extends PropNode {
|
||||
public int data;
|
||||
}
|
||||
|
||||
public static class IntArrayNode extends PropNode {
|
||||
public int[] data;
|
||||
}
|
||||
|
||||
public static class DoubleNode extends PropNode {
|
||||
public double data;
|
||||
}
|
||||
|
||||
public static class DoubleArrayNode extends PropNode {
|
||||
public double[] data;
|
||||
}
|
||||
}
|
90
src/com/gnarly/engine/properties/PropertyReader.java
Normal file
90
src/com/gnarly/engine/properties/PropertyReader.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
package com.gnarly.engine.properties;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Scanner;
|
||||
import com.gnarly.engine.properties.Properties.*;
|
||||
|
||||
public class PropertyReader {
|
||||
|
||||
private static int lineNum;
|
||||
private static String path;
|
||||
|
||||
public static Properties readProperties(String path) {
|
||||
Properties props = null;
|
||||
try {
|
||||
File file = new File(path);
|
||||
Scanner scanner = new Scanner(file);
|
||||
PropertyReader.path = path;
|
||||
lineNum = 0;
|
||||
props = readBlock(file.getName(), scanner).data;
|
||||
scanner.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
private static BlockNode readBlock(String name, Scanner scanner) {
|
||||
BlockNode props = new BlockNode();
|
||||
props.key = name;
|
||||
props.data = new Properties(name);
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
line = line.replaceAll("\\s", "");
|
||||
if(line.equals("}"))
|
||||
break;
|
||||
else if(line.length() < 2 || !line.substring(0, 2).equals("//")){
|
||||
String[] pair = line.split(":");
|
||||
if (pair.length != 2)
|
||||
throw new ImproperFormattingException("Formatting exception on line " + line + " in file '" + path + "!");
|
||||
pair[1] = pair[1].replaceAll("\\s", "");
|
||||
if (pair[1].equals("{"))
|
||||
props.data.add(readBlock(pair[0], scanner));
|
||||
else if (pair[1].matches("(\\d+|0x[\\da-f]+)")) {
|
||||
IntNode node = new IntNode();
|
||||
node.key = pair[0];
|
||||
node.data = Integer.decode(pair[1]);
|
||||
props.data.add(node);
|
||||
}
|
||||
else if (pair[1].matches("(\\d+|0x[\\d0-9]+)(,(\\d+|0x[\\d0-9]+))+")) {
|
||||
String[] data = pair[1].split(",");
|
||||
int[] ints = new int[data.length];
|
||||
for (int i = 0; i < ints.length; ++i)
|
||||
ints[i] = Integer.decode(data[i]);
|
||||
IntArrayNode node = new IntArrayNode();
|
||||
node.key = pair[0];
|
||||
node.data = ints;
|
||||
props.data.add(node);
|
||||
|
||||
}
|
||||
else if (pair[1].matches("\\d+\\.\\d+")) {
|
||||
DoubleNode node = new DoubleNode();
|
||||
node.key = pair[0];
|
||||
node.data = Double.parseDouble(pair[1]);
|
||||
props.data.add(node);
|
||||
}
|
||||
else if (pair[1].matches("\\d+\\.\\d+(,\\d+\\.\\d+)+")) {
|
||||
String[] data = pair[1].split(",");
|
||||
double[] doubles = new double[data.length];
|
||||
for (int i = 0; i < doubles.length; ++i)
|
||||
doubles[i] = Double.parseDouble(data[i]);
|
||||
DoubleArrayNode node = new DoubleArrayNode();
|
||||
node.key = pair[0];
|
||||
node.data = doubles;
|
||||
props.data.add(node);
|
||||
|
||||
}
|
||||
else {
|
||||
StringNode node = new StringNode();
|
||||
node.key = pair[0];
|
||||
node.data = pair[1];
|
||||
props.data.add(node);
|
||||
}
|
||||
}
|
||||
++lineNum;
|
||||
}
|
||||
return props;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.gnarly.engine.properties;
|
||||
|
||||
public class UndeclaredPropertyException extends Exception {
|
||||
|
||||
public UndeclaredPropertyException(String exception) {
|
||||
super(exception);
|
||||
}
|
||||
}
|
99
src/com/gnarly/engine/shaders/Shader.java
Normal file
99
src/com/gnarly/engine/shaders/Shader.java
Normal file
|
@ -0,0 +1,99 @@
|
|||
package com.gnarly.engine.shaders;
|
||||
|
||||
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
|
||||
import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
|
||||
import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER;
|
||||
import static org.lwjgl.opengl.GL20.glAttachShader;
|
||||
import static org.lwjgl.opengl.GL20.glCompileShader;
|
||||
import static org.lwjgl.opengl.GL20.glCreateProgram;
|
||||
import static org.lwjgl.opengl.GL20.glCreateShader;
|
||||
import static org.lwjgl.opengl.GL20.glDeleteProgram;
|
||||
import static org.lwjgl.opengl.GL20.glDeleteShader;
|
||||
import static org.lwjgl.opengl.GL20.glDetachShader;
|
||||
import static org.lwjgl.opengl.GL20.glGetShaderInfoLog;
|
||||
import static org.lwjgl.opengl.GL20.glGetShaderi;
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glLinkProgram;
|
||||
import static org.lwjgl.opengl.GL20.glShaderSource;
|
||||
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||
import static org.lwjgl.opengl.GL20.glUseProgram;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
public abstract class Shader {
|
||||
|
||||
public static Shader2c SHADER2C;
|
||||
public static Shader2t SHADER2T;
|
||||
|
||||
protected int program;
|
||||
|
||||
protected int mvpLoc;
|
||||
|
||||
protected Shader(String vertPath, String fragPath) {
|
||||
program = glCreateProgram();
|
||||
|
||||
int vert = loadShader(vertPath, GL_VERTEX_SHADER);
|
||||
int frag = loadShader(fragPath, GL_FRAGMENT_SHADER);
|
||||
|
||||
glAttachShader(program, vert);
|
||||
glAttachShader(program, frag);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
glDetachShader(program, vert);
|
||||
glDetachShader(program, frag);
|
||||
|
||||
glDeleteShader(vert);
|
||||
glDeleteShader(frag);
|
||||
|
||||
mvpLoc = glGetUniformLocation(program, "mvp");
|
||||
}
|
||||
|
||||
private int loadShader(String path, int type) {
|
||||
StringBuilder file = new StringBuilder();
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(new File(path)));
|
||||
String line;
|
||||
while((line = reader.readLine()) != null)
|
||||
file.append(line + '\n');
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
String source = file.toString();
|
||||
int shader = glCreateShader(type);
|
||||
glShaderSource(shader, source);
|
||||
glCompileShader(shader);
|
||||
if(glGetShaderi(shader, GL_COMPILE_STATUS) != 1)
|
||||
throw new RuntimeException("Failed to compile shader: " + path + "! " + glGetShaderInfoLog(shader));
|
||||
return shader;
|
||||
}
|
||||
|
||||
protected abstract void getUniforms();
|
||||
|
||||
public void setMVP(Matrix4f matrix) {
|
||||
glUniformMatrix4fv(mvpLoc, false, matrix.get(new float[16]));
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
glUseProgram(program);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
SHADER2C = new Shader2c();
|
||||
SHADER2T = new Shader2t();
|
||||
}
|
||||
}
|
27
src/com/gnarly/engine/shaders/Shader2c.java
Normal file
27
src/com/gnarly/engine/shaders/Shader2c.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package com.gnarly.engine.shaders;
|
||||
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
|
||||
public class Shader2c extends Shader {
|
||||
|
||||
int colorLoc;
|
||||
|
||||
protected Shader2c(String vert, String frag) {
|
||||
super(vert, frag);
|
||||
getUniforms();
|
||||
}
|
||||
|
||||
protected Shader2c() {
|
||||
super("res/shaders/s2c/vert.gls", "res/shaders/s2c/frag.gls");
|
||||
getUniforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getUniforms() {
|
||||
colorLoc = glGetUniformLocation(program, "iColor");
|
||||
}
|
||||
|
||||
public void setColor(float r, float g, float b, float a) {
|
||||
glUniform4f(colorLoc, r, g, b, a);
|
||||
}
|
||||
}
|
33
src/com/gnarly/engine/shaders/Shader2t.java
Normal file
33
src/com/gnarly/engine/shaders/Shader2t.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package com.gnarly.engine.shaders;
|
||||
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1f;
|
||||
import static org.lwjgl.opengl.GL20.glUniform4f;
|
||||
|
||||
public class Shader2t extends Shader {
|
||||
|
||||
private int alphaLoc;
|
||||
private int colorLoc;
|
||||
private int amountLoc;
|
||||
|
||||
protected Shader2t() {
|
||||
super("res/shaders/s2t/vert.gls", "res/shaders/s2t/frag.gls");
|
||||
getUniforms();
|
||||
}
|
||||
|
||||
public void setMixColor(float r, float g, float b, float a, float amount) {
|
||||
glUniform4f(colorLoc, r, g, b, a);
|
||||
glUniform1f(amountLoc, amount);
|
||||
}
|
||||
|
||||
public void setAlpha(float a) {
|
||||
glUniform1f(alphaLoc, a);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void getUniforms() {
|
||||
alphaLoc = glGetUniformLocation(program, "alpha");
|
||||
colorLoc = glGetUniformLocation(program, "iColor");
|
||||
amountLoc = glGetUniformLocation(program, "amount");
|
||||
}
|
||||
}
|
97
src/com/gnarly/engine/texture/Texture.java
Normal file
97
src/com/gnarly/engine/texture/Texture.java
Normal file
|
@ -0,0 +1,97 @@
|
|||
package com.gnarly.engine.texture;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_CLAMP;
|
||||
import static org.lwjgl.opengl.GL11.GL_NEAREST;
|
||||
import static org.lwjgl.opengl.GL11.GL_RGBA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL11.glDeleteTextures;
|
||||
import static org.lwjgl.opengl.GL11.glGenTextures;
|
||||
import static org.lwjgl.opengl.GL11.glTexImage2D;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameterf;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
import com.gnarly.engine.display.Window;
|
||||
|
||||
public class Texture {
|
||||
|
||||
protected int id, width, height;
|
||||
|
||||
public Texture(String name) {
|
||||
BufferedImage bi = null;
|
||||
try {
|
||||
bi = ImageIO.read(new File("res/img/" + Window.resolution + "/" + name));
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
bi = ImageIO.read(new File("res/img/const/" + name));
|
||||
} catch (IOException ex) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (bi != null) {
|
||||
width = bi.getWidth();
|
||||
height = bi.getHeight();
|
||||
int[] pixels = bi.getRGB(0, 0, width, height, null, 0, width);
|
||||
ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 4);
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
int pixel = pixels[i * width + j];
|
||||
buffer.put((byte)((pixel >> 16) & 0xFF)); // Red
|
||||
buffer.put((byte)((pixel >> 8) & 0xFF)); // Green
|
||||
buffer.put((byte)((pixel ) & 0xFF)); // Blue
|
||||
buffer.put((byte)((pixel >> 24) & 0xFF)); // Alpha
|
||||
}
|
||||
}
|
||||
buffer.flip();
|
||||
|
||||
id = glGenTextures();
|
||||
bind();
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
unbind();
|
||||
}
|
||||
}
|
||||
|
||||
public Texture(int id, int width, int height) {
|
||||
this.id = id;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
glDeleteTextures(id);
|
||||
}
|
||||
}
|
85
src/com/gnarly/game/Button.java
Normal file
85
src/com/gnarly/game/Button.java
Normal file
|
@ -0,0 +1,85 @@
|
|||
package com.gnarly.game;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_1;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
|
||||
public class Button {
|
||||
|
||||
public static final int
|
||||
UNPRESSED = 0,
|
||||
RELEASED = 1,
|
||||
PRESSED = 2,
|
||||
HELD = 3;
|
||||
|
||||
private Window window;
|
||||
private Camera camera;
|
||||
|
||||
private TexRect[] states;
|
||||
|
||||
private float x, y, width, height;
|
||||
|
||||
private int state, tex;
|
||||
|
||||
public Button(Window window, Camera camera, String tex1, String tex2, String tex3, float x, float y, float depth, float width, float height, boolean gui) {
|
||||
this.window = window;
|
||||
this.camera = camera;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
states = new TexRect[3];
|
||||
states[0] = new TexRect(camera, tex1, x, y, depth, width, height, 0, gui);
|
||||
states[1] = new TexRect(camera, tex2, x, y, depth, width, height, 0, gui);
|
||||
states[2] = new TexRect(camera, tex3, x, y, depth, width, height, 0, gui);
|
||||
tex = 0;
|
||||
state = 0;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if(contains(window.getMouseCoords(camera))) {
|
||||
if(window.mousePressed(GLFW_MOUSE_BUTTON_1) > Window.BUTTON_UNPRESSED) {
|
||||
tex = 2;
|
||||
if(state <= RELEASED)
|
||||
state = PRESSED;
|
||||
else
|
||||
state = HELD;
|
||||
}
|
||||
else {
|
||||
tex = 1;
|
||||
if(state >= PRESSED)
|
||||
state = RELEASED;
|
||||
else
|
||||
state = UNPRESSED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tex = 0;
|
||||
state = UNPRESSED;
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
states[tex].render();
|
||||
}
|
||||
|
||||
public boolean contains(Vector3f coords) {
|
||||
return coords.x >= x && coords.y >= y && coords.x < x + width && coords.y < y + height;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setTex(int tex) {
|
||||
this.tex = tex;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return states[0].getHeight();
|
||||
}
|
||||
}
|
42
src/com/gnarly/game/GamePanel.java
Normal file
42
src/com/gnarly/game/GamePanel.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package com.gnarly.game;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.game.play.Map;
|
||||
|
||||
public class GamePanel extends Panel {
|
||||
|
||||
private Window window;
|
||||
private Camera camera;
|
||||
|
||||
private Map map;
|
||||
|
||||
public GamePanel(Window window, Camera camera) {
|
||||
this.window = window;
|
||||
this.camera = camera;
|
||||
|
||||
map = new Map(window, camera);
|
||||
|
||||
state = Main.GAME_PANEL;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
map.update();
|
||||
if (map.isComplete())
|
||||
state = Main.OVER_PANEL;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
map.render();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
map = new Map(window, camera);
|
||||
}
|
||||
|
||||
public int checkState() {
|
||||
int state = this.state;
|
||||
this.state = Main.GAME_PANEL;
|
||||
return state;
|
||||
}
|
||||
}
|
85
src/com/gnarly/game/Main.java
Normal file
85
src/com/gnarly/game/Main.java
Normal file
|
@ -0,0 +1,85 @@
|
|||
package com.gnarly.game;
|
||||
|
||||
import com.gnarly.engine.audio.ALManagement;
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.engine.shaders.Shader;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static long FPS = 999;
|
||||
public static double dtime;
|
||||
|
||||
public static final int
|
||||
NUM_PANELS = 3,
|
||||
GAME_PANEL = 0,
|
||||
MENU_PANEL = 1,
|
||||
OVER_PANEL = 2;
|
||||
|
||||
private ALManagement al;
|
||||
|
||||
private Window window;
|
||||
private Camera camera;
|
||||
|
||||
private Panel[] panels;
|
||||
private int panel;
|
||||
|
||||
public void start() {
|
||||
long curTime, pastTime, nspf = 1000000000 / FPS;
|
||||
init();
|
||||
pastTime = System.nanoTime();
|
||||
while(!window.shouldClose()) {
|
||||
curTime = System.nanoTime();
|
||||
if (curTime - pastTime > nspf) {
|
||||
dtime = (curTime - pastTime) / 1000000000d;
|
||||
update();
|
||||
render();
|
||||
pastTime = curTime;
|
||||
}
|
||||
}
|
||||
al.destroy();
|
||||
Window.terminate();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
al = new ALManagement();
|
||||
window = new Window("Abraham", true);
|
||||
//window = new Window(100, 100, "Abraham", true, true, true);
|
||||
camera = new Camera(1920, 1080);
|
||||
Shader.init();
|
||||
|
||||
panels = new Panel[NUM_PANELS];
|
||||
panels[GAME_PANEL] = new GamePanel(window, camera);
|
||||
panels[MENU_PANEL] = new MenuPanel(window, camera);
|
||||
panels[OVER_PANEL] = new OverPanel(window, camera);
|
||||
panel = MENU_PANEL;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
window.update();
|
||||
int state = panels[panel].checkState();
|
||||
if (state != panel) {
|
||||
switch (state) {
|
||||
case GAME_PANEL:
|
||||
GamePanel game = (GamePanel) panels[GAME_PANEL];
|
||||
game.reset();
|
||||
case OVER_PANEL:
|
||||
OverPanel over = (OverPanel) panels[OVER_PANEL];
|
||||
over.setActive();
|
||||
}
|
||||
panel = state;
|
||||
}
|
||||
panels[panel].update();
|
||||
camera.update();
|
||||
}
|
||||
|
||||
private void render() {
|
||||
window.clear();
|
||||
panels[panel].render();
|
||||
window.swap();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Main().start();
|
||||
}
|
||||
}
|
69
src/com/gnarly/game/MenuPanel.java
Normal file
69
src/com/gnarly/game/MenuPanel.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
package com.gnarly.game;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Scanner;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.game.play.Map;
|
||||
import com.gnarly.game.play.NumberDisplay;
|
||||
|
||||
public class MenuPanel extends Panel {
|
||||
|
||||
private Window window;
|
||||
private Camera camera;
|
||||
|
||||
private TexRect background;
|
||||
|
||||
private Button playButton;
|
||||
|
||||
private TexRect scoreText;
|
||||
private NumberDisplay scoreDisplay;
|
||||
|
||||
public MenuPanel(Window window, Camera camera) {
|
||||
this.window = window;
|
||||
this.camera = camera;
|
||||
|
||||
background = new TexRect(camera, "MenuBackground.png", 0, 0, -0.5f, 1920, 1080, 0, true);
|
||||
|
||||
playButton = new Button(window, camera, "PlayDefault.png", "PlayHovered.png", "PlayPressed.png", (camera.getWidth() - 480) / 2, camera.getHeight() / 2 + 120, -0.1f, 480, 240, true);
|
||||
|
||||
scoreDisplay = new NumberDisplay(camera, camera.getWidth() / 2 - 300 + Map.SCALE * 4, camera.getHeight() / 2 + 140 + playButton.getHeight(), 0, 93, NumberDisplay.JUSTIFICATION_LEFT, 0, 8);
|
||||
scoreText = new TexRect(camera, "Highscore.png", camera.getWidth() / 2 - 500 - Map.SCALE * 4, camera.getHeight() / 2 + 145 + playButton.getHeight(), 0, 200, 83, 0, true);
|
||||
|
||||
state = Main.MENU_PANEL;
|
||||
|
||||
File file = new File("res/high.sco");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
Scanner scanner = new Scanner(file);
|
||||
scoreDisplay.setValue(scanner.nextInt());
|
||||
scanner.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
playButton.update();
|
||||
if (playButton.getState() == Button.RELEASED)
|
||||
state = Main.GAME_PANEL;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
background.render();
|
||||
playButton.render();
|
||||
scoreDisplay.render();
|
||||
scoreText.render();
|
||||
}
|
||||
|
||||
public int checkState() {
|
||||
int state = this.state;
|
||||
this.state = Main.MENU_PANEL;
|
||||
return state;
|
||||
}
|
||||
}
|
90
src/com/gnarly/game/OverPanel.java
Normal file
90
src/com/gnarly/game/OverPanel.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
package com.gnarly.game;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.engine.model.ColRect;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.game.play.Map;
|
||||
import com.gnarly.game.play.NumberDisplay;
|
||||
|
||||
public class OverPanel extends Panel {
|
||||
|
||||
private static final float FADE_TIME = 1.5f;
|
||||
|
||||
private Window window;
|
||||
private Camera camera;
|
||||
|
||||
private TexRect background;
|
||||
private ColRect overlay;
|
||||
|
||||
private Button playButton;
|
||||
|
||||
private TexRect scoreText;
|
||||
private NumberDisplay scoreDisplay;
|
||||
|
||||
private float time;
|
||||
|
||||
public OverPanel(Window window, Camera camera) {
|
||||
this.window = window;
|
||||
this.camera = camera;
|
||||
|
||||
background = new TexRect(camera, "GameOverBackground.png", 0, 0, -0.5f, 1920, 1080, 0, true);
|
||||
overlay = new ColRect(camera, 0, 0, 0, 1920, 1080, 0, 0, 0, 1, true);
|
||||
|
||||
playButton = new Button(window, camera, "AgainDefault.png", "AgainHovered.png", "AgainPressed.png", (camera.getWidth() - 480) / 2, camera.getHeight() / 2, -0.1f, 480, 240, true);
|
||||
|
||||
scoreDisplay = new NumberDisplay(camera, camera.getWidth() / 2 - 300 + Map.SCALE * 4, camera.getHeight() / 2 + 20 + playButton.getHeight(), -0.01f, 93, NumberDisplay.JUSTIFICATION_LEFT, 0, 8);
|
||||
scoreText = new TexRect(camera, "Highscore.png", camera.getWidth() / 2 - 500 - Map.SCALE * 4, camera.getHeight() / 2 + 25 + playButton.getHeight(), -0.01f, 200, 83, 0, true);
|
||||
|
||||
state = Main.OVER_PANEL;
|
||||
|
||||
loadScore();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (time > 0) {
|
||||
time -= Main.dtime;
|
||||
overlay.setAlpha(time / FADE_TIME);
|
||||
}
|
||||
playButton.update();
|
||||
if (playButton.getState() == Button.RELEASED)
|
||||
state = Main.GAME_PANEL;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
background.render();
|
||||
playButton.render();
|
||||
scoreDisplay.render();
|
||||
scoreText.render();
|
||||
if (time > 0)
|
||||
overlay.render();
|
||||
}
|
||||
|
||||
public void setActive() {
|
||||
loadScore();
|
||||
time = FADE_TIME;
|
||||
}
|
||||
|
||||
public int checkState() {
|
||||
int state = this.state;
|
||||
this.state = Main.OVER_PANEL;
|
||||
return state;
|
||||
}
|
||||
|
||||
public void loadScore() {
|
||||
File file = new File("res/high.sco");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
Scanner scanner = new Scanner(file);
|
||||
scoreDisplay.setValue(scanner.nextInt());
|
||||
scanner.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
src/com/gnarly/game/Panel.java
Normal file
10
src/com/gnarly/game/Panel.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package com.gnarly.game;
|
||||
|
||||
public abstract class Panel {
|
||||
|
||||
protected int state;
|
||||
|
||||
public abstract void update();
|
||||
public abstract void render();
|
||||
public abstract int checkState();
|
||||
}
|
74
src/com/gnarly/game/attack/AngerRam.java
Normal file
74
src/com/gnarly/game/attack/AngerRam.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
package com.gnarly.game.attack;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.ColRect;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.play.Map;
|
||||
import com.gnarly.game.play.Player;
|
||||
|
||||
public class AngerRam extends Attack {
|
||||
|
||||
private static final float WIDTH = 512;
|
||||
private static final float HEIGHT = 448;
|
||||
|
||||
private static final float MOVE_DELAY = 0.4f;
|
||||
private static final float BASE_DELAY = 1.4f;
|
||||
private static final float RUN_TIME = 1.5f;
|
||||
private static final float COMPLETE_TIME = 2.0f;
|
||||
|
||||
private static Texture angerRam;
|
||||
|
||||
private Camera camera;
|
||||
private Player player;
|
||||
|
||||
private TexRect ram;
|
||||
private ColRect trail;
|
||||
|
||||
private float time;
|
||||
|
||||
private boolean smote;
|
||||
private boolean complete;
|
||||
|
||||
public AngerRam(Camera camera, Player player) {
|
||||
if (angerRam == null)
|
||||
angerRam = new Texture("AngerRam.png");
|
||||
this.camera = camera;
|
||||
this.player = player;
|
||||
ram = new TexRect(camera, angerRam, -WIDTH, player.getY() + (player.getHeight() - HEIGHT) / 2, -0.03f, WIDTH, HEIGHT, 0, false);
|
||||
trail = new ColRect(camera, 0, ram.getY() + HEIGHT / 4, -0.03f, camera.getWidth(), HEIGHT / 2, 0.75f, 0, 0, 0.5f, false);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
time += Main.dtime;
|
||||
if (time < MOVE_DELAY / Map.timeScale)
|
||||
ram.setX(-WIDTH + WIDTH / 4 * time / MOVE_DELAY);
|
||||
else if (time > BASE_DELAY / Map.timeScale && ram.getX() < camera.getWidth()) {
|
||||
float newX = camera.getWidth() * (time - BASE_DELAY) / (RUN_TIME - BASE_DELAY);
|
||||
trail.setWidth(newX);
|
||||
if (ram.getX() + ram.getWidth() < player.getX() && newX + ram.getWidth() > player.getX() && player.getY() + player.getHeight() > ram.getY() && player.getY() < ram.getY() + ram.getHeight() * 0.8f)
|
||||
smote = true;
|
||||
ram.setX(newX);
|
||||
}
|
||||
else if (time > COMPLETE_TIME / Map.timeScale)
|
||||
complete = true;
|
||||
else if (time > RUN_TIME / Map.timeScale)
|
||||
trail.setColor(0.75f, 0, 0, 0.5f * (1 - (time - RUN_TIME) / (COMPLETE_TIME - RUN_TIME)));
|
||||
}
|
||||
|
||||
public void render() {
|
||||
if (time < RUN_TIME)
|
||||
ram.render();
|
||||
if (time > BASE_DELAY)
|
||||
trail.render();
|
||||
}
|
||||
|
||||
public boolean struckDown() {
|
||||
return smote;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
}
|
11
src/com/gnarly/game/attack/Attack.java
Normal file
11
src/com/gnarly/game/attack/Attack.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package com.gnarly.game.attack;
|
||||
|
||||
public abstract class Attack {
|
||||
|
||||
public int id;
|
||||
|
||||
public abstract void update();
|
||||
public abstract void render();
|
||||
public abstract boolean struckDown();
|
||||
public abstract boolean isComplete();
|
||||
}
|
80
src/com/gnarly/game/attack/AttackFactory.java
Normal file
80
src/com/gnarly/game/attack/AttackFactory.java
Normal file
|
@ -0,0 +1,80 @@
|
|||
package com.gnarly.game.attack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.game.play.Player;
|
||||
|
||||
public class AttackFactory {
|
||||
|
||||
public static final int ATTACK_COUNT = 3;
|
||||
public static final int ANGER_RAM = 0;
|
||||
public static final int FIREBALL = 1;
|
||||
public static final int LIGHTNING = 2;
|
||||
|
||||
private Camera camera;
|
||||
private Player player;
|
||||
private boolean active;
|
||||
|
||||
private ArrayList<Attack> attacks;
|
||||
|
||||
private SmoteCallback callback;
|
||||
|
||||
public AttackFactory(Camera camera, Player player, SmoteCallback callback) {
|
||||
this.camera = camera;
|
||||
this.player = player;
|
||||
attacks = new ArrayList<>();
|
||||
this.callback = callback;
|
||||
active = true;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
for (int i = 0; i < attacks.size(); ++i) {
|
||||
attacks.get(i).update();
|
||||
if (attacks.get(i).struckDown() && active) {
|
||||
callback.onSmote(attacks.get(i).id);
|
||||
active = false;
|
||||
}
|
||||
if (attacks.get(i).isComplete()) {
|
||||
attacks.remove(i--);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
for (int i = 0; i < attacks.size(); ++i)
|
||||
attacks.get(i).render();
|
||||
}
|
||||
|
||||
public void triggerRandom() {
|
||||
triggerNew((int) (Math.random() * ATTACK_COUNT));
|
||||
}
|
||||
|
||||
public void triggerNew(int type) {
|
||||
Attack addition = null;
|
||||
switch (type) {
|
||||
case ANGER_RAM:
|
||||
addition = new AngerRam(camera, player);
|
||||
addition.id = ANGER_RAM;
|
||||
break;
|
||||
case FIREBALL:
|
||||
addition = new Fireball(camera, player);
|
||||
addition.id = FIREBALL;
|
||||
break;
|
||||
case LIGHTNING:
|
||||
addition = new CloudStrike(camera, player);
|
||||
addition.id = LIGHTNING;
|
||||
break;
|
||||
}
|
||||
if (addition != null)
|
||||
attacks.add(addition);
|
||||
}
|
||||
|
||||
public void deactivate() {
|
||||
active = false;
|
||||
}
|
||||
|
||||
public void setActive() {
|
||||
active = true;
|
||||
}
|
||||
}
|
232
src/com/gnarly/game/attack/CloudStrike.java
Normal file
232
src/com/gnarly/game/attack/CloudStrike.java
Normal file
|
@ -0,0 +1,232 @@
|
|||
package com.gnarly.game.attack;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.ColRect;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.model.Vao;
|
||||
import com.gnarly.engine.shaders.Shader;
|
||||
import com.gnarly.engine.shaders.Shader2t;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.play.Map;
|
||||
import com.gnarly.game.play.Player;
|
||||
|
||||
public class CloudStrike extends Attack {
|
||||
|
||||
private static final float ENTER = 2;
|
||||
private static final float CHARGING = 3;
|
||||
private static final float FIRING = 3.3f;
|
||||
private static final float EXITING = 4.5f;
|
||||
|
||||
private static final float CLOUD_HEIGHT = -150;
|
||||
|
||||
private static final float BOLT_DURATION = 0.1f;
|
||||
private static final int NUM_BOLTS = 3;
|
||||
|
||||
private TexRect clouds;
|
||||
private TexRect charging;
|
||||
private TexRect striking;
|
||||
|
||||
private static Texture[] bolts;
|
||||
private Bolt lightning;
|
||||
private ColRect flash;
|
||||
|
||||
private Camera camera;
|
||||
private Player player;
|
||||
|
||||
private boolean targeted;
|
||||
private boolean complete;
|
||||
private boolean smote;
|
||||
|
||||
private float targetX;
|
||||
private float targetY;
|
||||
private float cloudX;
|
||||
|
||||
private int bolt;
|
||||
private float boltTime;
|
||||
|
||||
private float startX;
|
||||
private float startY;
|
||||
|
||||
private float time;
|
||||
|
||||
public CloudStrike(Camera camera, Player player) {
|
||||
if (bolts == null) {
|
||||
bolts = new Texture[3];
|
||||
bolts[0] = new Texture("0LightningBolt.png");
|
||||
bolts[1] = new Texture("1LightningBolt.png");
|
||||
bolts[2] = new Texture("2LightningBolt.png");
|
||||
}
|
||||
|
||||
clouds = new TexRect(camera, "StormCloud.png", 0, 0, -0.04f, 720, 351, 0, true);
|
||||
charging = new TexRect(camera, "StormCloudCharge.png", 0, 0, -0.03f, 720, 351, 0, true);
|
||||
striking = new TexRect(camera, "StormCloudStrike.png", 0, 0, -0.03f, 720, 467, 0, true);
|
||||
lightning = new Bolt(camera, 227, 2156);
|
||||
flash = new ColRect(camera, 0, 0, 0, camera.getWidth(), camera.getHeight(), 0.41f, 0.8f, 1, 1, true);
|
||||
charging.setAlpha(0);
|
||||
|
||||
this.camera = camera;
|
||||
this.player = player;
|
||||
targeted = false;
|
||||
complete = false;
|
||||
smote = false;
|
||||
bolt = 0;
|
||||
cloudX = (float) ((camera.getWidth() - clouds.getWidth() - Map.SCALE * 4) * Math.random() + Map.SCALE * 2);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
time += Main.dtime;
|
||||
if (time < ENTER) {
|
||||
clouds.setPosition(cloudX + (camera.getWidth() - cloudX) * (1 - (time / ENTER)), CLOUD_HEIGHT);
|
||||
}
|
||||
else if (time < CHARGING) {
|
||||
if (!targeted) {
|
||||
charging.setPosition(clouds.getX(), clouds.getY());
|
||||
striking.setPosition(clouds.getX(), clouds.getY());
|
||||
targetX = player.getX() + player.getWidth() / 2;
|
||||
targetY = player.getY() + player.getHeight() / 2 - camera.getY();
|
||||
targeted = true;
|
||||
|
||||
startX = cloudX + clouds.getWidth() / 2;
|
||||
startY = CLOUD_HEIGHT + clouds.getHeight() * 3 / 4;
|
||||
|
||||
float angle = (float) (Math.atan2(targetY - startY, targetX - startX) - Math.PI / 2);
|
||||
|
||||
lightning.set(startX, startY, angle);
|
||||
}
|
||||
charging.setAlpha((time - ENTER) / (CHARGING - ENTER));
|
||||
}
|
||||
else if (time < FIRING) {
|
||||
boltTime += Main.dtime;
|
||||
while (boltTime > BOLT_DURATION) {
|
||||
bolt = (bolt + 1) % NUM_BOLTS;
|
||||
boltTime -= BOLT_DURATION;
|
||||
}
|
||||
lightning.setTexture(bolts[bolt]);
|
||||
float value = (0.75f * (1 - (time - CHARGING) / (FIRING - CHARGING)));
|
||||
flash.setAlpha(value * value * value * value);
|
||||
|
||||
int[] side = new int[4];
|
||||
side[0] = checkSide(player.getX(), player.getY() - camera.getY());
|
||||
side[1] = checkSide(player.getX() + player.getWidth(), player.getY() - camera.getY());
|
||||
side[2] = checkSide(player.getX(), player.getY() + player.getHeight() - camera.getY());
|
||||
side[3] = checkSide(player.getX() + player.getWidth(), player.getY() + player.getHeight() - camera.getY());
|
||||
|
||||
for (int i = 1; i < side.length; ++i)
|
||||
if (side[i] != side[0])
|
||||
smote = true;
|
||||
}
|
||||
else if (time < EXITING)
|
||||
clouds.setPosition(-clouds.getWidth() + (cloudX + clouds.getWidth()) * (1 - ((time - FIRING) / (EXITING - FIRING))), CLOUD_HEIGHT);
|
||||
else
|
||||
complete = true;
|
||||
}
|
||||
|
||||
private int checkSide(float x, float y) {
|
||||
int side = 0;
|
||||
|
||||
if (targetY != startY) {
|
||||
float slope = (float) ((targetY - startY) / (targetX - startX));
|
||||
|
||||
float boltY = startY + slope * (x - startX);
|
||||
if (y < boltY)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
}
|
||||
else {
|
||||
if (x < startX)
|
||||
side = 0;
|
||||
else
|
||||
side = 1;
|
||||
}
|
||||
return side;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
if (time < CHARGING) {
|
||||
clouds.render();
|
||||
charging.render();
|
||||
}
|
||||
else if (time < FIRING) {
|
||||
if (bolt == 2)
|
||||
charging.render();
|
||||
else
|
||||
striking.render();
|
||||
lightning.render();
|
||||
flash.render();
|
||||
}
|
||||
else
|
||||
clouds.render();
|
||||
}
|
||||
|
||||
public boolean struckDown() {
|
||||
return smote;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
private static class Bolt {
|
||||
|
||||
private static Vao vao;
|
||||
|
||||
private Texture texture;
|
||||
private Shader2t shader;
|
||||
|
||||
private Camera camera;
|
||||
|
||||
float x;
|
||||
float y;
|
||||
float angle;
|
||||
float width;
|
||||
float height;
|
||||
|
||||
public Bolt(Camera camera, float width, float height) {
|
||||
this.camera = camera;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
shader = Shader.SHADER2T;
|
||||
|
||||
float vertices[] = {
|
||||
0.5f, 0, 0, // Top left
|
||||
0.5f, 1, 0, // Bottom left
|
||||
-0.5f, 1, 0, // Bottom right
|
||||
-0.5f, 0, 0 // Top right
|
||||
};
|
||||
int indices[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
float[] texCoords = {
|
||||
1, 0,
|
||||
1, 1,
|
||||
0, 1,
|
||||
0, 0
|
||||
};
|
||||
vao = new Vao(vertices, indices);
|
||||
vao.addAttrib(texCoords, 2);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
texture.bind();
|
||||
shader.enable();
|
||||
shader.setMVP(camera.getProjection().translate(x, y, -0.15f).rotateZ(angle).scale(width, height, 1));
|
||||
vao.render();
|
||||
shader.disable();
|
||||
texture.unbind();
|
||||
}
|
||||
|
||||
public void setTexture(Texture texture) {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public void set(float x, float y, float angle) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.angle = angle;
|
||||
}
|
||||
}
|
||||
}
|
58
src/com/gnarly/game/attack/Fireball.java
Normal file
58
src/com/gnarly/game/attack/Fireball.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
package com.gnarly.game.attack;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.play.Map;
|
||||
import com.gnarly.game.play.Player;
|
||||
|
||||
public class Fireball extends Attack {
|
||||
|
||||
private static final float MIN_SPEED = 280 * Map.SCALE;
|
||||
private static final float MAX_SPEED = 360 * Map.SCALE;
|
||||
|
||||
private static Texture fireball;
|
||||
|
||||
private Camera camera;
|
||||
private Player player;
|
||||
|
||||
private TexRect incendiary;
|
||||
|
||||
private float speed;
|
||||
private float time;
|
||||
|
||||
private boolean complete;
|
||||
private boolean smote;
|
||||
|
||||
public Fireball(Camera camera, Player player) {
|
||||
this.camera = camera;
|
||||
this.player = player;
|
||||
if (fireball == null)
|
||||
fireball = new Texture("Fireball.png");
|
||||
incendiary = new TexRect(camera, fireball, (float) (Map.SCALE + Math.random() * (camera.getWidth() - 46 * Map.SCALE)), Map.MAP_HEIGHT, -0.03f, 48 * Map.SCALE, 64 * Map.SCALE, 0, false);
|
||||
speed = (float) (Map.MAP_HEIGHT / (MIN_SPEED + (MAX_SPEED - MIN_SPEED) * Math.random() * Map.timeScale));
|
||||
time = 0;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
time += Main.dtime;
|
||||
incendiary.setY((1 - (time / speed)) * Map.MAP_HEIGHT);
|
||||
if (incendiary.getY() < player.getY() + player.getHeight() && incendiary.getY() + incendiary.getHeight() > player.getY() && incendiary.getX() < player.getX() + player.getWidth() && incendiary.getX() + incendiary.getWidth() > player.getX())
|
||||
smote = true;
|
||||
if (incendiary.getY() <= -incendiary.getHeight())
|
||||
complete = true;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
incendiary.render();
|
||||
}
|
||||
|
||||
public boolean struckDown() {
|
||||
return smote;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
}
|
6
src/com/gnarly/game/attack/SmoteCallback.java
Normal file
6
src/com/gnarly/game/attack/SmoteCallback.java
Normal file
|
@ -0,0 +1,6 @@
|
|||
package com.gnarly.game.attack;
|
||||
|
||||
public interface SmoteCallback {
|
||||
|
||||
public void onSmote(int type);
|
||||
}
|
70
src/com/gnarly/game/platforms/EarthPlatform.java
Normal file
70
src/com/gnarly/game/platforms/EarthPlatform.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
|
||||
package com.gnarly.game.platforms;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.play.Map;
|
||||
|
||||
public class EarthPlatform extends Platform {
|
||||
|
||||
public TexRect leftRect;
|
||||
public TexRect centerRect;
|
||||
public TexRect rightRect;
|
||||
|
||||
private int segments;
|
||||
|
||||
public EarthPlatform(Camera camera, float x, float y, int width) {
|
||||
super(x, x + width * WIDTH, y);
|
||||
segments = width;
|
||||
if (leftRect == null) {
|
||||
leftRect = new TexRect(camera, "EarthPlatformLeft.png", 0, 0, -0.05f, WIDTH, 32 * Map.SCALE, 0, false);
|
||||
centerRect = new TexRect(camera, "EarthPlatformCenter.png", 0, 0, -0.05f, WIDTH, 32 * Map.SCALE, 0, false);
|
||||
rightRect = new TexRect(camera, "EarthPlatformRight.png", 0, 0, -0.05f, WIDTH, 32 * Map.SCALE, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (flag == FLAG_DELETE) {
|
||||
time += Main.dtime;
|
||||
float amount = (float) (Math.sin(Math.PI * 2 * time / PULSE_SPEED / Map.timeScale) + 1) / 4 + 0.25f;
|
||||
leftRect.setMix( 0.5f, 0, 0, 1, amount);
|
||||
centerRect.setMix(0.5f, 0, 0, 1, amount);
|
||||
rightRect.setMix( 0.5f, 0, 0, 1, amount);
|
||||
leftRect.setAlpha(1);
|
||||
centerRect.setAlpha(1);
|
||||
rightRect.setAlpha(1);
|
||||
}
|
||||
else if (flag == FLAG_CREATE) {
|
||||
time += Main.dtime;
|
||||
float amount = 0.5f - (float) (Math.sin(Math.PI * 2 * time / PULSE_SPEED / Map.timeScale) + 1) / 8;
|
||||
leftRect.setMix(0, 1, 0, 1, 0.85f);
|
||||
centerRect.setMix(0, 1, 0, 1, 0.85f);
|
||||
rightRect.setMix(0, 1, 0, 1, 0.85f);
|
||||
leftRect.setAlpha(amount);
|
||||
centerRect.setAlpha(amount);
|
||||
rightRect.setAlpha(amount);
|
||||
}
|
||||
else {
|
||||
time = 0;
|
||||
leftRect.setMix(0.5f, 1, 0.6f, 1, 0);
|
||||
centerRect.setMix(0.5f, 1, 0.6f, 1, 0);
|
||||
rightRect.setMix(0.5f, 1, 0.6f, 1, 0);
|
||||
leftRect.setAlpha(1);
|
||||
centerRect.setAlpha(1);
|
||||
rightRect.setAlpha(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
leftRect.setPosition(left, y);
|
||||
leftRect.render();
|
||||
centerRect.setPosition(left, y);
|
||||
for (int i = 1; i < segments - 1; ++i) {
|
||||
centerRect.translate(WIDTH, 0, 0);
|
||||
centerRect.render();
|
||||
}
|
||||
rightRect.setPosition(right - WIDTH, y);
|
||||
rightRect.render();
|
||||
}
|
||||
}
|
70
src/com/gnarly/game/platforms/HeavenPlatform.java
Normal file
70
src/com/gnarly/game/platforms/HeavenPlatform.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
|
||||
package com.gnarly.game.platforms;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.play.Map;
|
||||
|
||||
public class HeavenPlatform extends Platform {
|
||||
|
||||
public TexRect leftRect;
|
||||
public TexRect centerRect;
|
||||
public TexRect rightRect;
|
||||
|
||||
private int segments;
|
||||
|
||||
public HeavenPlatform(Camera camera, float x, float y, int width) {
|
||||
super(x, x + width * WIDTH, y);
|
||||
segments = width;
|
||||
if (leftRect == null) {
|
||||
leftRect = new TexRect(camera, "HeavenPlatformLeft.png", 0, 0, -0.05f, WIDTH, 19 * Map.SCALE, 0, false);
|
||||
centerRect = new TexRect(camera, "HeavenPlatformCenter.png", 0, 0, -0.05f, WIDTH, 19 * Map.SCALE, 0, false);
|
||||
rightRect = new TexRect(camera, "HeavenPlatformRight.png", 0, 0, -0.05f, WIDTH, 19 * Map.SCALE, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (flag == FLAG_DELETE) {
|
||||
time += Main.dtime;
|
||||
float amount = (float) (Math.sin(Math.PI * 2 * time / PULSE_SPEED / Map.timeScale) + 1) / 4 + 0.25f;
|
||||
leftRect.setMix( 0.5f, 0, 0, 1, amount);
|
||||
centerRect.setMix(0.5f, 0, 0, 1, amount);
|
||||
rightRect.setMix( 0.5f, 0, 0, 1, amount);
|
||||
leftRect.setAlpha(1);
|
||||
centerRect.setAlpha(1);
|
||||
rightRect.setAlpha(1);
|
||||
}
|
||||
else if (flag == FLAG_CREATE) {
|
||||
time += Main.dtime;
|
||||
float amount = (float) (Math.sin(Math.PI * 2 * time / PULSE_SPEED / Map.timeScale) + 1) / 16 + 0.125f;
|
||||
leftRect.setMix(0, 1, 0, 1, 0.5f);
|
||||
centerRect.setMix(0, 1, 0, 1, 0.5f);
|
||||
rightRect.setMix(0, 1, 0, 1, 0.5f);
|
||||
leftRect.setAlpha(amount);
|
||||
centerRect.setAlpha(amount);
|
||||
rightRect.setAlpha(amount);
|
||||
}
|
||||
else {
|
||||
time = 0;
|
||||
leftRect.setMix(0, 0, 0, 1, 0);
|
||||
centerRect.setMix(0, 0, 0, 1, 0);
|
||||
rightRect.setMix(0, 0, 0, 1, 0);
|
||||
leftRect.setAlpha(1);
|
||||
centerRect.setAlpha(1);
|
||||
rightRect.setAlpha(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
leftRect.setPosition(left, y - 1 * Map.SCALE);
|
||||
leftRect.render();
|
||||
centerRect.setPosition(left, y - 1 * Map.SCALE);
|
||||
for (int i = 1; i < segments - 1; ++i) {
|
||||
centerRect.translate(WIDTH, 0, 0);
|
||||
centerRect.render();
|
||||
}
|
||||
rightRect.setPosition(right - WIDTH, y - 1 * Map.SCALE);
|
||||
rightRect.render();
|
||||
}
|
||||
}
|
70
src/com/gnarly/game/platforms/HellPlatform.java
Normal file
70
src/com/gnarly/game/platforms/HellPlatform.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
|
||||
package com.gnarly.game.platforms;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.play.Map;
|
||||
|
||||
public class HellPlatform extends Platform {
|
||||
|
||||
public TexRect leftRect;
|
||||
public TexRect centerRect;
|
||||
public TexRect rightRect;
|
||||
|
||||
private int segments;
|
||||
|
||||
public HellPlatform(Camera camera, float x, float y, int width) {
|
||||
super(x, x + width * WIDTH, y);
|
||||
segments = width;
|
||||
if (leftRect == null) {
|
||||
leftRect = new TexRect(camera, "HellPlatformLeft.png", 0, 0, -0.05f, WIDTH, 19 * Map.SCALE, 0, false);
|
||||
centerRect = new TexRect(camera, "HellPlatformCenter.png", 0, 0, -0.05f, WIDTH, 19 * Map.SCALE, 0, false);
|
||||
rightRect = new TexRect(camera, "HellPlatformRight.png", 0, 0, -0.05f, WIDTH, 19 * Map.SCALE, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (flag == FLAG_DELETE) {
|
||||
time += Main.dtime;
|
||||
float amount = (float) (Math.sin(Math.PI * 2 * time / PULSE_SPEED / Map.timeScale) + 1) / 4 + 0.25f;
|
||||
leftRect.setMix( 0.5f, 0, 0, 1, amount);
|
||||
centerRect.setMix(0.5f, 0, 0, 1, amount);
|
||||
rightRect.setMix( 0.5f, 0, 0, 1, amount);
|
||||
leftRect.setAlpha(1);
|
||||
centerRect.setAlpha(1);
|
||||
rightRect.setAlpha(1);
|
||||
}
|
||||
else if (flag == FLAG_CREATE) {
|
||||
time += Main.dtime;
|
||||
float amount = 0.5f - (float) (Math.sin(Math.PI * 2 * time / PULSE_SPEED / Map.timeScale) + 1) / 8;
|
||||
leftRect.setMix(0, 1, 0, 1, 0.85f);
|
||||
centerRect.setMix(0, 1, 0, 1, 0.85f);
|
||||
rightRect.setMix(0, 1, 0, 1, 0.85f);
|
||||
leftRect.setAlpha(amount);
|
||||
centerRect.setAlpha(amount);
|
||||
rightRect.setAlpha(amount);
|
||||
}
|
||||
else {
|
||||
time = 0;
|
||||
leftRect.setMix(0.5f, 1, 0.6f, 1, 0);
|
||||
centerRect.setMix(0.5f, 1, 0.6f, 1, 0);
|
||||
rightRect.setMix(0.5f, 1, 0.6f, 1, 0);
|
||||
leftRect.setAlpha(1);
|
||||
centerRect.setAlpha(1);
|
||||
rightRect.setAlpha(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
leftRect.setPosition(left, y - 3 * Map.SCALE);
|
||||
leftRect.render();
|
||||
centerRect.setPosition(left, y - 3 * Map.SCALE);
|
||||
for (int i = 1; i < segments - 1; ++i) {
|
||||
centerRect.translate(WIDTH, 0, 0);
|
||||
centerRect.render();
|
||||
}
|
||||
rightRect.setPosition(right - WIDTH, y - 3 * Map.SCALE);
|
||||
rightRect.render();
|
||||
}
|
||||
}
|
79
src/com/gnarly/game/platforms/Platform.java
Normal file
79
src/com/gnarly/game/platforms/Platform.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package com.gnarly.game.platforms;
|
||||
|
||||
import com.gnarly.game.play.Map;
|
||||
import com.gnarly.game.play.Player;
|
||||
import com.gnarly.game.play.Ram;
|
||||
|
||||
public abstract class Platform {
|
||||
|
||||
protected static final float PULSE_SPEED = 2;
|
||||
|
||||
public static final float WIDTH = 32 * Map.SCALE;
|
||||
|
||||
public static final int FLAG_NONE = 0;
|
||||
public static final int FLAG_DELETE = 1;
|
||||
public static final int FLAG_CREATE = 2;
|
||||
|
||||
protected float left;
|
||||
protected float right;
|
||||
protected float y;
|
||||
|
||||
protected int flag;
|
||||
protected float time;
|
||||
|
||||
public Platform(float left, float right, float y) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.y = y;
|
||||
flag = FLAG_NONE;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public float getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public float getCenter() {
|
||||
return (left + right) / 2;
|
||||
}
|
||||
|
||||
public boolean playerPassthrough(Player player) {
|
||||
return (player.getPastY() + player.getHeight() <= y && player.getY() + player.getHeight() > y && player.getX() + 3 * Map.SCALE <= right && player.getX() + player.getWidth() - 3 * Map.SCALE >= left);
|
||||
}
|
||||
|
||||
public boolean ramPassthrough(Ram ram) {
|
||||
return (ram.getPastY() + ram.getHeight() <= y && ram.getY() + ram.getHeight() > y && ram.getX() + 3 * Map.SCALE <= right && ram.getX() + ram.getWidth() - 3 * Map.SCALE >= left);
|
||||
}
|
||||
|
||||
public void flagDelete(boolean delete) {
|
||||
if (delete)
|
||||
flag = FLAG_DELETE;
|
||||
else
|
||||
flag = FLAG_NONE;
|
||||
}
|
||||
|
||||
public void flagCreate(boolean create) {
|
||||
if (create)
|
||||
flag = FLAG_CREATE;
|
||||
else
|
||||
flag = FLAG_NONE;
|
||||
}
|
||||
|
||||
public int getFlag() {
|
||||
return flag;
|
||||
}
|
||||
|
||||
public boolean compare(Platform platform) {
|
||||
return (platform.left == left && platform.right == right && platform.y == y);
|
||||
}
|
||||
|
||||
public abstract void update();
|
||||
public abstract void render();
|
||||
}
|
80
src/com/gnarly/game/platforms/PlatformFactory.java
Normal file
80
src/com/gnarly/game/platforms/PlatformFactory.java
Normal file
|
@ -0,0 +1,80 @@
|
|||
package com.gnarly.game.platforms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.game.play.Map;
|
||||
|
||||
public class PlatformFactory {
|
||||
|
||||
public static final int MAX_STAGE = 4;
|
||||
|
||||
public static Platform makePlatform(Camera camera, float x, float y, int width) {
|
||||
if (y < camera.getHeight())
|
||||
return new HeavenPlatform(camera, x, y, width);
|
||||
else if (y < camera.getHeight() * 2)
|
||||
return new EarthPlatform(camera, x, y, width);
|
||||
else
|
||||
return new HellPlatform(camera, x, y, width);
|
||||
}
|
||||
|
||||
public static void loadStage(ArrayList<Platform> platforms, Camera camera, int stage) {
|
||||
platforms.clear();
|
||||
switch (stage) {
|
||||
case 0:
|
||||
platforms.add(makePlatform(camera, camera.getWidth() / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() * 2 / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 2 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() * 2 / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 2 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 3 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() * 2 / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 3 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 4 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() * 2 / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 4 / 5, 3));
|
||||
break;
|
||||
case 1:
|
||||
platforms.add(makePlatform(camera, camera.getWidth() * 2 / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 2 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() * 2 / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 3 / 5, 3));
|
||||
platforms.add(makePlatform(camera, camera.getWidth() / 3 - Platform.WIDTH * 1.5f, Map.MAP_HEIGHT * 4 / 5, 3));
|
||||
break;
|
||||
case 2:
|
||||
platforms.add(PlatformFactory.makePlatform(camera, (camera.getWidth() - Platform.WIDTH * 4) / 2, camera.getHeight() / 2, 4));
|
||||
platforms.add(PlatformFactory.makePlatform(camera, (camera.getWidth() - Platform.WIDTH * 4) / 2, camera.getHeight() * 3 / 2, 4));
|
||||
platforms.add(PlatformFactory.makePlatform(camera, (camera.getWidth() - Platform.WIDTH * 4) / 2, camera.getHeight() * 5 / 2, 4));
|
||||
break;
|
||||
case 3:
|
||||
platforms.add(PlatformFactory.makePlatform(camera, (camera.getWidth() - Platform.WIDTH * 6) / 2, camera.getHeight() * 5 / 2, 6));
|
||||
break;
|
||||
case 4:
|
||||
platforms.add(PlatformFactory.makePlatform(camera, (camera.getWidth() - Platform.WIDTH * 2) / 2, camera.getHeight() * 5 / 2, 2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void advanceLevel(ArrayList<Platform> platforms, ArrayList<Platform> nextSet) {
|
||||
for (int i = 0; i < platforms.size(); ++i)
|
||||
if (platforms.get(i).getFlag() == Platform.FLAG_DELETE)
|
||||
platforms.remove(i--);
|
||||
while (nextSet.size() > 0) {
|
||||
nextSet.get(0).flagCreate(false);
|
||||
platforms.add(nextSet.get(0));
|
||||
nextSet.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void compareStage(ArrayList<Platform> platforms, ArrayList<Platform> nextSet, Camera camera, int stage) {
|
||||
loadStage(nextSet, camera, stage);
|
||||
for (int i = 0; i < platforms.size(); ++i)
|
||||
platforms.get(i).flagDelete(true);
|
||||
for (int i = 0; i < nextSet.size(); ++i)
|
||||
nextSet.get(i).flagCreate(true);
|
||||
for (int i = 0; i < platforms.size(); ++i) {
|
||||
for (int j = 0; j < nextSet.size(); ++j) {
|
||||
if (platforms.get(i).compare(nextSet.get(j))) {
|
||||
platforms.get(i).flagDelete(false);
|
||||
nextSet.remove(j--);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
372
src/com/gnarly/game/play/Map.java
Normal file
372
src/com/gnarly/game/play/Map.java
Normal file
|
@ -0,0 +1,372 @@
|
|||
package com.gnarly.game.play;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
import com.gnarly.game.attack.AttackFactory;
|
||||
import com.gnarly.game.platforms.Platform;
|
||||
import com.gnarly.game.platforms.PlatformFactory;
|
||||
|
||||
public class Map {
|
||||
|
||||
private static final float PLATFORM_DELAY = 5;
|
||||
|
||||
private static final int ADVANCE_LEVEL = 25;
|
||||
|
||||
private static final float ATTACK_RATE = 5;
|
||||
|
||||
private static final float GRAVITY_UP = 2400;
|
||||
private static final float GRAVITY_DOWN = 3000;
|
||||
private static final float FALL = 3200;
|
||||
|
||||
public static final float SCALE = 4;
|
||||
|
||||
public static float MAP_HEIGHT;
|
||||
|
||||
private static final int BABY_RATE = 7;
|
||||
|
||||
private static final int NO_DEATH = 0;
|
||||
private static final int DEVIL_SNATCH = 1;
|
||||
private static final int RAM_SMASHING = 2;
|
||||
private static final int INCINERATION = 3;
|
||||
private static final int ELECTROCUTION = 4;
|
||||
|
||||
private static Texture DEVIL_HAND;
|
||||
private static Texture FLYING_ABRAHAM;
|
||||
private static Texture CRISPY_ABRAHAM;
|
||||
private static Texture[] SHOCKED_ABRAHAM;
|
||||
|
||||
private static final float SHOCK_FRAME_LENGTH = 0.15f;
|
||||
|
||||
public static float timeScale = 1;
|
||||
|
||||
private Camera camera;
|
||||
|
||||
private Player player;
|
||||
private ArrayList<Sacrifice> sacrifices;
|
||||
private ArrayList<Platform> platforms;
|
||||
private ArrayList<Platform> nextSet;
|
||||
|
||||
private TexRect background;
|
||||
|
||||
private float sacrificesAtATime = 2;
|
||||
private int numSacrifices = 0;
|
||||
private int totalSacrifices = 0;
|
||||
|
||||
private int death = NO_DEATH;
|
||||
private float deathTime = 0;
|
||||
|
||||
private TexRect deathRect;
|
||||
|
||||
private AttackFactory attacks;
|
||||
private float attackTime;
|
||||
|
||||
private Vector3f velocity;
|
||||
|
||||
private int shockFrame;
|
||||
|
||||
private int lastScore;
|
||||
private int score;
|
||||
private int stage;
|
||||
|
||||
private float platformTime;
|
||||
|
||||
private boolean complete;
|
||||
|
||||
private TexRect scoreText;
|
||||
private NumberDisplay scoreDisplay;
|
||||
|
||||
public Map(Window window, Camera camera) {
|
||||
MAP_HEIGHT = camera.getHeight() * 3;
|
||||
|
||||
this.camera = camera;
|
||||
platforms = new ArrayList<>();
|
||||
nextSet = new ArrayList<>();
|
||||
player = new Player(window, camera);
|
||||
|
||||
background = new TexRect(camera, "background.png", 0, 0, -0.2f, camera.getWidth(), MAP_HEIGHT, 0, false);
|
||||
|
||||
sacrifices = new ArrayList<>();
|
||||
|
||||
if (DEVIL_HAND == null) {
|
||||
DEVIL_HAND = new Texture("AbrahamDevilSnatch.png");
|
||||
FLYING_ABRAHAM = new Texture("AbrahamRamSmash.png");
|
||||
CRISPY_ABRAHAM = new Texture("AbrahamFried.png");
|
||||
|
||||
SHOCKED_ABRAHAM = new Texture[4];
|
||||
SHOCKED_ABRAHAM[0] = new Texture("AbrahamShocked0.png");
|
||||
SHOCKED_ABRAHAM[1] = new Texture("AbrahamShocked1.png");
|
||||
SHOCKED_ABRAHAM[2] = new Texture("AbrahamShocked2.png");
|
||||
SHOCKED_ABRAHAM[3] = new Texture("AbrahamShocked3.png");
|
||||
}
|
||||
|
||||
deathRect = new TexRect(camera, DEVIL_HAND, 0, 0, 0, 0, 0, 0, false);
|
||||
|
||||
attacks = new AttackFactory(camera, player, (int id) -> {
|
||||
switch (id) {
|
||||
case AttackFactory.ANGER_RAM:
|
||||
death = RAM_SMASHING;
|
||||
deathRect.setTexture(FLYING_ABRAHAM);
|
||||
deathRect.set(player.getX(), player.getY(), player.getWidth(), player.getHeight());
|
||||
velocity.set(500 * SCALE, -500 * SCALE, 0);
|
||||
break;
|
||||
case AttackFactory.FIREBALL:
|
||||
death = INCINERATION;
|
||||
deathRect.setTexture(CRISPY_ABRAHAM);
|
||||
deathRect.set(player.getX(), player.getY(), player.getWidth(), player.getHeight());
|
||||
velocity.set(0, -20 * SCALE, 0);
|
||||
break;
|
||||
case AttackFactory.LIGHTNING:
|
||||
death = ELECTROCUTION;
|
||||
deathRect.setTexture(SHOCKED_ABRAHAM[0]);
|
||||
deathRect.set(player.getX(), player.getY(), player.getWidth(), player.getHeight());
|
||||
shockFrame = 0;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
velocity = new Vector3f();
|
||||
|
||||
scoreDisplay = new NumberDisplay(camera, camera.getWidth() / 2 - 300 + Map.SCALE * 4, 10, 0, 93, NumberDisplay.JUSTIFICATION_LEFT, 0, 8);
|
||||
|
||||
scoreText = new TexRect(camera, "Score.png", camera.getWidth() / 2 - 500 - Map.SCALE * 4, 10, 0, 200, 93, 0, true);
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
switch (death) {
|
||||
case NO_DEATH:
|
||||
for (int i = 0; i < platforms.size(); ++i)
|
||||
platforms.get(i).update();
|
||||
for (int i = 0; i < nextSet.size(); ++i)
|
||||
nextSet.get(i).update();
|
||||
|
||||
if (platformTime > 0) {
|
||||
platformTime -= Main.dtime;
|
||||
if (platformTime < 0)
|
||||
PlatformFactory.advanceLevel(platforms, nextSet);
|
||||
}
|
||||
else if (stage != PlatformFactory.MAX_STAGE && score - lastScore >= ADVANCE_LEVEL) {
|
||||
platformTime = PLATFORM_DELAY / timeScale;
|
||||
PlatformFactory.compareStage(platforms, nextSet, camera, ++stage);
|
||||
lastScore = score;
|
||||
}
|
||||
|
||||
sacrificesAtATime += Main.dtime / 100;
|
||||
while (numSacrifices < (int) sacrificesAtATime)
|
||||
spawnSacrifice();
|
||||
|
||||
player.update();
|
||||
for (int i = 0; i < sacrifices.size(); ++i) {
|
||||
sacrifices.get(i).update();
|
||||
if (sacrifices.get(i).shouldRemove()) {
|
||||
score += sacrifices.get(i).getPoints();
|
||||
sacrifices.remove(i--);
|
||||
--numSacrifices;
|
||||
}
|
||||
}
|
||||
boolean playerCollided = false;
|
||||
for (int i = 0; i < platforms.size(); ++i) {
|
||||
Platform curPlatform = platforms.get(i);
|
||||
if (!player.shouldFallThrough() && curPlatform.playerPassthrough(player) && curPlatform.getY() < player.getY() + player.getHeight()) {
|
||||
player.setY(curPlatform.getY() - player.getHeight());
|
||||
player.hitPlatform();
|
||||
playerCollided = true;
|
||||
}
|
||||
for (int j = 0; j < sacrifices.size(); ++j) {
|
||||
Sacrifice sacrifice = sacrifices.get(j);
|
||||
if (sacrifice instanceof Ram) {
|
||||
Ram ram = (Ram) sacrifice;
|
||||
if (!ram.shouldFallThrough() && curPlatform.ramPassthrough(ram) && curPlatform.getY() < ram.getY() + ram.getHeight()) {
|
||||
ram.setY(curPlatform.getY() - ram.getHeight());
|
||||
ram.hitPlatform();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!playerCollided)
|
||||
player.inFreeFall();
|
||||
for (int i = 0; i < sacrifices.size(); ++i)
|
||||
player.attemptSacrifice(sacrifices.get(i));
|
||||
if (player.getX() < 0)
|
||||
player.setX(0);
|
||||
else if (player.getX() + player.getWidth() > camera.getWidth())
|
||||
player.setX(camera.getWidth() - player.getWidth());
|
||||
if (player.getY() < 0) {
|
||||
player.setY(0);
|
||||
player.setYVelocity(0);
|
||||
}
|
||||
else if (player.getY() + player.getHeight() > MAP_HEIGHT) {
|
||||
death = DEVIL_SNATCH;
|
||||
deathRect.setTexture(DEVIL_HAND);
|
||||
deathRect.set(player.getX(), MAP_HEIGHT - 24 * SCALE, 16 * SCALE, 24 * SCALE);
|
||||
attacks.deactivate();
|
||||
}
|
||||
camera.setY(player.getY() + (player.getHeight() - camera.getHeight()) / 2);
|
||||
if (camera.getY() < 0)
|
||||
camera.setY(0);
|
||||
else if (camera.getY() + camera.getHeight() > MAP_HEIGHT)
|
||||
camera.setY(MAP_HEIGHT - camera.getHeight());
|
||||
|
||||
attackTime += Main.dtime * timeScale;
|
||||
if (attackTime > ATTACK_RATE) {
|
||||
attacks.triggerRandom();
|
||||
attackTime -= ATTACK_RATE;
|
||||
}
|
||||
|
||||
timeScale += Main.dtime / 200;
|
||||
if (timeScale > 4)
|
||||
timeScale = 4;
|
||||
break;
|
||||
case DEVIL_SNATCH:
|
||||
deathTime += Main.dtime;
|
||||
if (deathTime > 1)
|
||||
deathRect.translate(0, (float) (32 * SCALE * Main.dtime), 0);
|
||||
if (deathRect.getY() >= MAP_HEIGHT)
|
||||
complete = true;
|
||||
break;
|
||||
case RAM_SMASHING:
|
||||
if (velocity.y < FALL) {
|
||||
if (velocity.y < 0)
|
||||
velocity.y += GRAVITY_UP * Main.dtime;
|
||||
else
|
||||
velocity.y += GRAVITY_DOWN * Main.dtime;
|
||||
}
|
||||
else
|
||||
velocity.y = FALL;
|
||||
|
||||
deathRect.translate(velocity.mul((float) Main.dtime, new Vector3f()));
|
||||
if (deathRect.getX() >= camera.getWidth())
|
||||
complete = true;
|
||||
break;
|
||||
case INCINERATION:
|
||||
if (velocity.y < FALL) {
|
||||
if (velocity.y < 0)
|
||||
velocity.y += GRAVITY_UP * Main.dtime;
|
||||
else
|
||||
velocity.y += GRAVITY_DOWN * Main.dtime;
|
||||
}
|
||||
else
|
||||
velocity.y = FALL;
|
||||
|
||||
deathRect.translate(velocity.mul((float) Main.dtime, new Vector3f()));
|
||||
if (deathRect.getY() >= MAP_HEIGHT)
|
||||
complete = true;
|
||||
break;
|
||||
case ELECTROCUTION:
|
||||
if (shockFrame < SHOCKED_ABRAHAM.length - 1) {
|
||||
deathTime += Main.dtime;
|
||||
shockFrame = (int) (deathTime / SHOCK_FRAME_LENGTH);
|
||||
if (shockFrame >= SHOCKED_ABRAHAM.length - 1) {
|
||||
shockFrame = SHOCKED_ABRAHAM.length - 1;
|
||||
velocity.set(0, -20 * SCALE, 0);
|
||||
}
|
||||
deathRect.setTexture(SHOCKED_ABRAHAM[shockFrame]);
|
||||
}
|
||||
else {
|
||||
if (velocity.y < FALL) {
|
||||
if (velocity.y < 0)
|
||||
velocity.y += GRAVITY_UP * Main.dtime;
|
||||
else
|
||||
velocity.y += GRAVITY_DOWN * Main.dtime;
|
||||
}
|
||||
else
|
||||
velocity.y = FALL;
|
||||
|
||||
deathRect.translate(velocity.mul((float) Main.dtime, new Vector3f()));
|
||||
if (deathRect.getY() >= MAP_HEIGHT)
|
||||
complete = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
attacks.update();
|
||||
scoreDisplay.setValue(score);
|
||||
}
|
||||
|
||||
public void spawnSacrifice() {
|
||||
boolean cegg = totalSacrifices % 10 == 0 && totalSacrifices > 0;
|
||||
if (totalSacrifices % BABY_RATE == 0 && totalSacrifices != 0)
|
||||
sacrifices.add(new SinusoidalBaby(camera, player.getY(), (int) Math.round(Math.random()) * 2 - 1, cegg));
|
||||
else {
|
||||
Platform platform = platforms.get((int) ((Math.random() * 100000) % platforms.size()));
|
||||
float min = platform.getLeft() - Ram.WIDTH + SCALE;
|
||||
float max = platform.getRight() - SCALE;
|
||||
sacrifices.add(new Ram(camera, (float) (min + (max - min) * Math.random()), platform.getY() - 64 * SCALE, cegg));
|
||||
}
|
||||
++numSacrifices;
|
||||
++totalSacrifices;
|
||||
}
|
||||
|
||||
public void render() {
|
||||
background.render();
|
||||
for (int i = 0; i < nextSet.size(); ++i)
|
||||
nextSet.get(i).render();
|
||||
for (int i = 0; i < platforms.size(); ++i)
|
||||
platforms.get(i).render();
|
||||
if (death == NO_DEATH)
|
||||
player.render();
|
||||
else
|
||||
deathRect.render();
|
||||
for (int i = 0; i < sacrifices.size(); ++i)
|
||||
sacrifices.get(i).render();
|
||||
attacks.render();
|
||||
scoreText.render();
|
||||
scoreDisplay.render();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
sacrifices.clear();
|
||||
stage = 0;
|
||||
PlatformFactory.loadStage(platforms, camera, 0);
|
||||
nextSet.clear();
|
||||
Platform platform = platforms.get((int) ((Math.random() * 100000) % platforms.size()));
|
||||
player.setX(platform.getCenter() - player.getWidth() / 2);
|
||||
player.setY(platform.getY() - player.getHeight());
|
||||
attacks.setActive();
|
||||
score = 0;
|
||||
timeScale = 1;
|
||||
complete = false;
|
||||
death = 0;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
if (complete) {
|
||||
File file = new File("res/high.sco");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
Scanner scanner = new Scanner(file);
|
||||
int highscore = scanner.nextInt();
|
||||
if (score > highscore) {
|
||||
PrintWriter writer = new PrintWriter(file);
|
||||
writer.write(Long.toString(score));
|
||||
writer.close();
|
||||
}
|
||||
scanner.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
PrintWriter writer = new PrintWriter(file);
|
||||
writer.write(Long.toString(score));
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return complete;
|
||||
}
|
||||
}
|
137
src/com/gnarly/game/play/NumberDisplay.java
Normal file
137
src/com/gnarly/game/play/NumberDisplay.java
Normal file
|
@ -0,0 +1,137 @@
|
|||
package com.gnarly.game.play;
|
||||
|
||||
import org.joml.Vector2f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
|
||||
public class NumberDisplay {
|
||||
|
||||
public static final int
|
||||
JUSTIFICATION_LEFT = 0,
|
||||
JUSTIFICATION_CENTER = 1,
|
||||
JUSTIFICATION_RIGHT = 2;
|
||||
|
||||
public static Texture[] nums;
|
||||
|
||||
private static final float DIMENSION_RATIO = 1;
|
||||
|
||||
private Camera camera;
|
||||
|
||||
private long num;
|
||||
private int minDigits;
|
||||
|
||||
private int justification;
|
||||
private float x, y, height;
|
||||
|
||||
private TexRect display;
|
||||
|
||||
public NumberDisplay(Camera camera, float x, float y, float z, float height, int justification, long number, int minDigits) {
|
||||
this.camera = camera;
|
||||
this.num = number;
|
||||
this.minDigits = minDigits;
|
||||
this.justification = justification;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.height = height;
|
||||
if(nums == null) {
|
||||
nums = new Texture[10];
|
||||
for (int i = 0; i < 10; ++i)
|
||||
nums[i] = new Texture(i + "digit.png");
|
||||
}
|
||||
display = new TexRect(camera, nums[0], 0, 0, z, 0, 0, 0, true);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
float width = height * DIMENSION_RATIO;
|
||||
float x = this.x;
|
||||
String text = Long.toString(num);
|
||||
int numDigits = Math.max(minDigits, text.length());
|
||||
if(justification == JUSTIFICATION_CENTER)
|
||||
x -= (numDigits / 2.0f) * width;
|
||||
else if(justification == JUSTIFICATION_RIGHT)
|
||||
x -= numDigits * width;
|
||||
display.setX(x);
|
||||
display.setY(y);
|
||||
display.setHeight(height);
|
||||
display.setWidth(width);
|
||||
for(int i = 0; i < numDigits; ++i) {
|
||||
int index = 0;
|
||||
if(i + text.length() - numDigits > -1) {
|
||||
if(text.charAt(i + text.length() - numDigits) == 'r')
|
||||
index = 16;
|
||||
else if(text.charAt(i + text.length() - numDigits) == 'o')
|
||||
index = 17;
|
||||
else if(text.charAt(i + text.length() - numDigits) >= 'a')
|
||||
index = text.charAt(i + text.length() - numDigits) - 87;
|
||||
else
|
||||
index = text.charAt(i + text.length() - numDigits) - 48;
|
||||
}
|
||||
display.setTexture(nums[index]);
|
||||
display.render();
|
||||
display.translate(width, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public void setValue(long num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
public void add(long num) {
|
||||
this.num += num;
|
||||
}
|
||||
|
||||
public void sub(long num) {
|
||||
this.num -= num;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
++num;
|
||||
}
|
||||
|
||||
public void decrement() {
|
||||
--num;
|
||||
}
|
||||
|
||||
public void setHeight(float height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setDigitWidth(float width) {
|
||||
this.height = width / DIMENSION_RATIO;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public Vector2f getPosition() {
|
||||
return new Vector2f(x, y);
|
||||
}
|
||||
|
||||
public Vector2f getPosition(int justification) {
|
||||
return new Vector2f(x, y);
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
188
src/com/gnarly/game/play/Player.java
Normal file
188
src/com/gnarly/game/play/Player.java
Normal file
|
@ -0,0 +1,188 @@
|
|||
package com.gnarly.game.play;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_A;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_D;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_J;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_K;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_S;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_SPACE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_W;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.display.Window;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
|
||||
public class Player extends TexRect {
|
||||
|
||||
private static final float STAB_DELAY = 0.15f;
|
||||
private static final float DASH_SPEED = 2000;
|
||||
private static final float DASH_DELAY = 0.4f;
|
||||
private static final float DASH_TIME = 0.15f;
|
||||
private static final float DASH_RESET = 1;
|
||||
private static final float SPEED = 384;
|
||||
private static final float GROUND_JUMP = 1280;
|
||||
private static final float AERIAL_JUMP = 900;
|
||||
private static final float GRAVITY_UP = 2400;
|
||||
private static final float GRAVITY_DOWN = 3000;
|
||||
private static final float FALL = 3200;
|
||||
private static final int NUM_JUMPS = 8;
|
||||
|
||||
private Window window;
|
||||
|
||||
private Vector3f oldPosition;
|
||||
private Vector3f velocity;
|
||||
|
||||
private boolean didHitPlatform = true;
|
||||
|
||||
private boolean fallThrough = false;
|
||||
|
||||
private float dashTime = -DASH_RESET;
|
||||
private float stabTime;
|
||||
|
||||
private Texture stand;
|
||||
private Texture stab;
|
||||
private Texture dash;
|
||||
|
||||
private float jumpForce;
|
||||
private int numJumps;
|
||||
|
||||
public Player(Window window, Camera camera) {
|
||||
super(camera, "AbrahamStand.png", 0, 0, -0.1f, 16 * Map.SCALE, 16 * Map.SCALE, 0, false);
|
||||
this.window = window;
|
||||
oldPosition = new Vector3f();
|
||||
velocity = new Vector3f();
|
||||
stand = new Texture("AbrahamStand.png");
|
||||
stab = new Texture("AbrahamStab.png");
|
||||
dash = new Texture("AbrahamDash.png");
|
||||
}
|
||||
|
||||
public void update() {
|
||||
oldPosition.set(position);
|
||||
|
||||
fallThrough = false;
|
||||
if (didHitPlatform) {
|
||||
velocity.y = 0;
|
||||
didHitPlatform = false;
|
||||
}
|
||||
|
||||
velocity.x = 0;
|
||||
|
||||
double delta = Main.dtime;
|
||||
setTexture(stand);
|
||||
|
||||
if (stabTime > 0) {
|
||||
setTexture(stab);
|
||||
stabTime -= delta;
|
||||
}
|
||||
|
||||
if (dashTime > 0) {
|
||||
setTexture(dash);
|
||||
if (delta > dashTime) {
|
||||
double tdelta = delta;
|
||||
position.x += (float) (direction * DASH_SPEED * dashTime * ((Map.timeScale - 1) * 0.25 + 1));
|
||||
delta -= dashTime;
|
||||
dashTime -= tdelta;
|
||||
}
|
||||
else {
|
||||
velocity.x = (float) (direction * DASH_SPEED * delta * ((Map.timeScale - 1) * 0.25 + 1));
|
||||
dashTime -= delta;
|
||||
delta = 0;
|
||||
}
|
||||
}
|
||||
else if (dashTime > -DASH_DELAY / Map.timeScale) {
|
||||
setTexture(dash);
|
||||
dashTime -= delta;
|
||||
}
|
||||
else if (dashTime > -DASH_RESET / Map.timeScale) {
|
||||
dashTime -= delta;
|
||||
}
|
||||
|
||||
if ((window.keyPressed(GLFW_KEY_W) == Window.BUTTON_PRESSED || window.keyPressed(GLFW_KEY_SPACE) == Window.BUTTON_PRESSED) && numJumps < NUM_JUMPS) {
|
||||
velocity.y = -(float) (jumpForce * ((Map.timeScale - 1) * 0.5 + 1));
|
||||
++numJumps;
|
||||
}
|
||||
if (window.keyPressed(GLFW_KEY_A) >= Window.BUTTON_PRESSED && dashTime <= 0) {
|
||||
velocity.x = -(float) (SPEED * Map.timeScale * delta);
|
||||
direction = -1;
|
||||
}
|
||||
if (window.keyPressed(GLFW_KEY_S) >= Window.BUTTON_PRESSED)
|
||||
fallThrough = true;
|
||||
if (window.keyPressed(GLFW_KEY_D) >= Window.BUTTON_PRESSED && dashTime <= 0) {
|
||||
velocity.x = (float) (SPEED * Map.timeScale * delta);
|
||||
direction = 1;
|
||||
}
|
||||
if (window.keyPressed(GLFW_KEY_J) == Window.BUTTON_PRESSED && dashTime <= -DASH_RESET / Map.timeScale) {
|
||||
dashTime = DASH_TIME;
|
||||
stabTime = 0;
|
||||
}
|
||||
else if (window.keyPressed(GLFW_KEY_K) == Window.BUTTON_PRESSED && stabTime <= 0 && dashTime <= 0) {
|
||||
stabTime = STAB_DELAY;
|
||||
}
|
||||
|
||||
if (velocity.y < FALL) {
|
||||
if (velocity.y < 0)
|
||||
velocity.y += GRAVITY_UP * Map.timeScale * Main.dtime;
|
||||
else
|
||||
velocity.y += GRAVITY_DOWN * Map.timeScale * Main.dtime;
|
||||
}
|
||||
else
|
||||
velocity.y = FALL;
|
||||
|
||||
position.add(velocity.x, (float) (velocity.y * Main.dtime), 0);
|
||||
}
|
||||
|
||||
public void attemptSacrifice(Sacrifice sacrifice) {
|
||||
if (dashTime > 0 &&
|
||||
sacrifice.getY() < position.y + 11 * Map.SCALE &&
|
||||
sacrifice.getY() + sacrifice.getHeight() > position.y + 10 * Map.SCALE &&
|
||||
((direction == -1 && oldPosition.x > sacrifice.getX() && position.x < sacrifice.getX() + sacrifice.getWidth()) ||
|
||||
(direction == 1 && oldPosition.x + width < sacrifice.getX() + sacrifice.getWidth() && position.x + width > sacrifice.getX()))) {
|
||||
sacrifice.sacrifice();
|
||||
}
|
||||
else if (stabTime > 0 &&
|
||||
sacrifice.getY() < position.y + 11 * Map.SCALE &&
|
||||
sacrifice.getY() + sacrifice.getHeight() > position.y + 10 * Map.SCALE &&
|
||||
((direction == -1 && position.x < sacrifice.getX() + sacrifice.getWidth() && position.x > sacrifice.getX()) ||
|
||||
(direction == 1 && position.x + width > sacrifice.getX() && position.x + width < sacrifice.getX() + sacrifice.getWidth()))) {
|
||||
sacrifice.sacrifice();
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
super.render();
|
||||
}
|
||||
|
||||
public void hitPlatform() {
|
||||
didHitPlatform = true;
|
||||
numJumps = 0;
|
||||
jumpForce = GROUND_JUMP;
|
||||
}
|
||||
|
||||
public float getPastX() {
|
||||
return oldPosition.x;
|
||||
}
|
||||
|
||||
public float getPastY() {
|
||||
return oldPosition.y;
|
||||
}
|
||||
|
||||
public float getTimeScale(float scale) {
|
||||
return Map.timeScale;
|
||||
}
|
||||
|
||||
public boolean shouldFallThrough() {
|
||||
return fallThrough;
|
||||
}
|
||||
|
||||
public void setYVelocity(float velocity) {
|
||||
this.velocity.y = velocity;
|
||||
}
|
||||
|
||||
public void inFreeFall() {
|
||||
jumpForce = AERIAL_JUMP;
|
||||
}
|
||||
}
|
97
src/com/gnarly/game/play/Ram.java
Normal file
97
src/com/gnarly/game/play/Ram.java
Normal file
|
@ -0,0 +1,97 @@
|
|||
package com.gnarly.game.play;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
|
||||
public class Ram extends TexRect implements Sacrifice {
|
||||
|
||||
public static final float WIDTH = 24 * Map.SCALE;
|
||||
|
||||
private static final float GRAVITY_UP = 2400;
|
||||
private static final float GRAVITY_DOWN = 3000;
|
||||
private static final float FALL = 3200;
|
||||
|
||||
private static Texture stand;
|
||||
private static Texture dead;
|
||||
private static Texture cstand;
|
||||
private static Texture cdead;
|
||||
|
||||
private Vector3f oldPosition;
|
||||
private Vector3f velocity;
|
||||
|
||||
private boolean didHitPlatform = true;
|
||||
private boolean fallThrough = false;
|
||||
|
||||
private int score = 0;
|
||||
|
||||
private boolean cegg;
|
||||
|
||||
public Ram(Camera camera, float x, float y, boolean cegg) {
|
||||
super(camera, stand, x, y, -0.15f, WIDTH, 16 * Map.SCALE, 0, false);
|
||||
if (stand == null) {
|
||||
stand = new Texture("Ram.png");
|
||||
dead = new Texture("RipRam.png");
|
||||
cstand = new Texture("CRam.png");
|
||||
cdead = new Texture("CRipRam.png");
|
||||
}
|
||||
this.cegg = cegg;
|
||||
oldPosition = new Vector3f();
|
||||
velocity = new Vector3f();
|
||||
if (!cegg)
|
||||
setTexture(stand);
|
||||
else
|
||||
setTexture(cstand);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
oldPosition.set(position);
|
||||
if (didHitPlatform) {
|
||||
velocity.y = 0;
|
||||
didHitPlatform = false;
|
||||
}
|
||||
|
||||
if (velocity.y < FALL) {
|
||||
if (velocity.y < 0)
|
||||
velocity.y += GRAVITY_UP * Map.timeScale * Main.dtime;
|
||||
else
|
||||
velocity.y += GRAVITY_DOWN * Map.timeScale * Main.dtime;
|
||||
}
|
||||
else
|
||||
velocity.y = FALL;
|
||||
|
||||
position.add(velocity.mul((float) Main.dtime, new Vector3f()));
|
||||
}
|
||||
|
||||
public float getPastY() {
|
||||
return oldPosition.y;
|
||||
}
|
||||
|
||||
public void hitPlatform() {
|
||||
didHitPlatform = true;
|
||||
}
|
||||
|
||||
public void sacrifice() {
|
||||
score = 1;
|
||||
if (!cegg)
|
||||
setTexture(dead);
|
||||
else
|
||||
setTexture(cdead);
|
||||
fallThrough = true;
|
||||
}
|
||||
|
||||
public boolean shouldFallThrough() {
|
||||
return fallThrough;
|
||||
}
|
||||
|
||||
public boolean shouldRemove() {
|
||||
return position.y > Map.MAP_HEIGHT;
|
||||
}
|
||||
|
||||
public int getPoints() {
|
||||
return score;
|
||||
}
|
||||
}
|
14
src/com/gnarly/game/play/Sacrifice.java
Normal file
14
src/com/gnarly/game/play/Sacrifice.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package com.gnarly.game.play;
|
||||
|
||||
public interface Sacrifice {
|
||||
|
||||
public void update();
|
||||
public void render();
|
||||
public float getX();
|
||||
public float getY();
|
||||
public float getWidth();
|
||||
public float getHeight();
|
||||
public void sacrifice();
|
||||
public boolean shouldRemove();
|
||||
public int getPoints();
|
||||
}
|
150
src/com/gnarly/game/play/SinusoidalBaby.java
Normal file
150
src/com/gnarly/game/play/SinusoidalBaby.java
Normal file
|
@ -0,0 +1,150 @@
|
|||
package com.gnarly.game.play;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import com.gnarly.engine.display.Camera;
|
||||
import com.gnarly.engine.model.TexRect;
|
||||
import com.gnarly.engine.texture.Texture;
|
||||
import com.gnarly.game.Main;
|
||||
|
||||
public class SinusoidalBaby extends TexRect implements Sacrifice {
|
||||
|
||||
public static final float HEIGHT = 16 * Map.SCALE;
|
||||
|
||||
private static final float BASE_FLUX_HEIGHT = 40 * Map.SCALE;
|
||||
private static final int MIN_FLUXES = 2;
|
||||
private static final int MAX_FLUXES = 10;
|
||||
private static final float MIN_SPEED = 50 * Map.SCALE;
|
||||
private static final float MAX_SPEED = 80 * Map.SCALE;
|
||||
|
||||
private static final float GRAVITY_UP = 2400;
|
||||
private static final float GRAVITY_DOWN = 3000;
|
||||
private static final float FALL = 3200;
|
||||
|
||||
private static float nextFlux = generateFlux();
|
||||
|
||||
private static Texture idle;
|
||||
private static Texture head;
|
||||
private static Texture body;
|
||||
private static Texture cidle;
|
||||
private static Texture chead;
|
||||
private static Texture cbody;
|
||||
|
||||
private float fluxHeight;
|
||||
private float numFluxes;
|
||||
private float speed;
|
||||
private float time;
|
||||
private float baseHeight;
|
||||
private float direction;
|
||||
|
||||
private boolean sacrificed;
|
||||
private TexRect severedHead;
|
||||
private Vector3f headVelocity;
|
||||
private Vector3f bodyVelocity;
|
||||
|
||||
private int score = 0;
|
||||
|
||||
private boolean cegg;
|
||||
|
||||
public SinusoidalBaby(Camera camera, float y, int direction, boolean cegg) {
|
||||
super(camera, idle, -16 * Map.SCALE, 0, -0.15f, 16 * Map.SCALE, 16 * Map.SCALE, 0, false);
|
||||
if (idle == null) {
|
||||
idle = new Texture("BabyTPose.png");
|
||||
head = new Texture("BabyHead.png");
|
||||
body = new Texture("BabyBody.png");
|
||||
cidle = new Texture("CBabyTPose.png");
|
||||
chead = new Texture("CBabyHead.png");
|
||||
cbody = new Texture("CBabyBody.png");
|
||||
}
|
||||
this.cegg = cegg;
|
||||
if (!cegg)
|
||||
setTexture(idle);
|
||||
else
|
||||
setTexture(cidle);
|
||||
this.direction = direction;
|
||||
if (direction < 0)
|
||||
position.x = camera.getWidth();
|
||||
baseHeight = y;
|
||||
fluxHeight = nextFlux;
|
||||
nextFlux = generateFlux();
|
||||
numFluxes = (float) (2 * Math.PI * (MIN_FLUXES + (MAX_FLUXES * Map.timeScale - MIN_FLUXES) * Math.random()));
|
||||
speed = camera.getWidth() / (float) (MIN_SPEED + (MAX_SPEED * Map.timeScale - MIN_SPEED) * Math.random());
|
||||
time = 0;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (!sacrificed) {
|
||||
time += Main.dtime;
|
||||
float x = time / speed;
|
||||
position.x = x * (camera.getWidth() + 16 * Map.SCALE) - 16 * Map.SCALE;
|
||||
if (direction < 0)
|
||||
position.x = camera.getWidth() - position.x;
|
||||
position.y = (float) (baseHeight + Math.sin(x * numFluxes) * fluxHeight);
|
||||
}
|
||||
else {
|
||||
if (headVelocity.y < FALL) {
|
||||
if (headVelocity.y < 0)
|
||||
headVelocity.y += GRAVITY_UP * Main.dtime;
|
||||
else
|
||||
headVelocity.y += GRAVITY_DOWN * Main.dtime;
|
||||
}
|
||||
else
|
||||
headVelocity.y = FALL;
|
||||
|
||||
severedHead.translate(headVelocity.mul((float) Main.dtime, new Vector3f()));
|
||||
|
||||
if (bodyVelocity.y < FALL) {
|
||||
if (bodyVelocity.y < 0)
|
||||
bodyVelocity.y += GRAVITY_UP * Main.dtime;
|
||||
else
|
||||
bodyVelocity.y += GRAVITY_DOWN * Main.dtime;
|
||||
}
|
||||
else
|
||||
bodyVelocity.y = FALL;
|
||||
|
||||
position.add(bodyVelocity.mul((float) Main.dtime, new Vector3f()));
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
if (sacrificed)
|
||||
severedHead.render();
|
||||
super.render();
|
||||
}
|
||||
|
||||
public void sacrifice() {
|
||||
sacrificed = true;
|
||||
if (!cegg) {
|
||||
severedHead = new TexRect(camera, head, position.x, position.y, -0.15f, 6 * Map.SCALE, 6 * Map.SCALE, 0, false);
|
||||
setTexture(body);
|
||||
}
|
||||
else {
|
||||
severedHead = new TexRect(camera, chead, position.x, position.y, -0.15f, 6 * Map.SCALE, 6 * Map.SCALE, 0, false);
|
||||
setTexture(cbody);
|
||||
}
|
||||
headVelocity = new Vector3f(0, -500 * Map.timeScale, 0);
|
||||
bodyVelocity = new Vector3f(0, 0, 0);
|
||||
score = 3;
|
||||
}
|
||||
|
||||
public boolean shouldRemove() {
|
||||
if (!sacrificed)
|
||||
return (direction == 1 && position.x >= camera.getWidth()) ||
|
||||
(direction == -1 && position.x <= -16 * Map.SCALE);
|
||||
else {
|
||||
return severedHead.getY() > Map.MAP_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
private static float generateFlux() {
|
||||
return (float) (Math.random() / 8 + 0.875) * BASE_FLUX_HEIGHT * Map.timeScale;
|
||||
}
|
||||
|
||||
public static float getFlux() {
|
||||
return nextFlux;
|
||||
}
|
||||
|
||||
public int getPoints() {
|
||||
return score;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue