A sky roads like game with interesting shaders
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 

202 lines
5.0 KiB

//
// Game.h
// SkyRoads
//
// Created by Joshua Moerman on 12/22/12.
// Copyright (c) 2012 Vadovas. All rights reserved.
//
#ifndef SkyRoads_Game_h
#define SkyRoads_Game_h
#import <GLKit/GLKit.h>
#include "statics.h"
#include "myGL.h"
static const float accel = 4.0;
static const float max_speed = 9.0;
struct Game{
std::vector<Quad> quads;
std::vector<Vertex> spaceship;
struct Position {
float x, y, z;
} position;
struct Speed {
float x, y, z;
} speed;
struct Box {
Position min, max;
} boundingbox;
Game()
: position({0.0, -1.0, 0.0})
, speed({0.0, 0.0, 0.0})
, boundingbox({-0.2, 0.0, -0.3, 0.2, 0.0, 0.3})
{
make_spaceship();
make_quads();
}
void make_spaceship(){
spaceship.resize(5);
spaceship[0] = {-1.0, 0.0, 2.0, 0.5, 0.0, 0.0, 0.0};
spaceship[1] = { 1.0, 0.0, 2.0, 0.5, 0.0, 0.0, 0.0};
spaceship[2] = { 0.0, 1.0, 1.5, 1.0, 0.2, 0.0, 0.0};
spaceship[3] = { 0.0, 0.0, -2.0, 1.0, 0.0, 1.5, 0.0};
spaceship[4] = {-1.0, 0.0, 2.0, 0.5, 0.0, 0.0, 0.0};
float scale = 0.7;
for(auto& v : spaceship){
v = gl::scale(v, scale*0.3, scale*0.2, scale*0.4);
}
}
void make_quads(){
quads.reserve(number_of_quads);
for(int zz = 0; zz < level_length; ++zz){
for(int xx = 0; xx < level_width; ++xx){
if(level[xx + level_width*zz] == 0) continue;
const double size = 1.0; // DONT CHANGE
double x = xx - (int)level_width/2;
double z = zz;
double y = -1.0;
Quad q;
// deg.
q[0][0] = x - size*0.5;
q[0][1] = y;
q[0][2] = z - size*0.5;
q[1][0] = x - size*0.5;
q[1][1] = y;
q[1][2] = z - size*0.5;
// real quad
q[2][0] = x - size*0.5;
q[2][1] = y;
q[2][2] = z - size*0.5;
q[3][0] = x - size*0.5;
q[3][1] = y;
q[3][2] = z + size*0.5;
q[4][0] = x + size*0.5;
q[4][1] = y;
q[4][2] = z - size*0.5;
q[5][0] = x + size*0.5;
q[5][1] = y;
q[5][2] = z + size*0.5;
// deg.
q[6][0] = x + size*0.5;
q[6][1] = y;
q[6][2] = z + size*0.5;
q[7][0] = x + size*0.5;
q[7][1] = y;
q[7][2] = z + size*0.5;
//double r = rand() / (double) RAND_MAX;
//double g = rand() / (double) RAND_MAX;
//double b = rand() / (double) RAND_MAX;
for(auto& v : q){
v[3] = 0.2*std::abs(x);
v[4] = 1.0 - 0.2*std::abs(x);
v[5] = (level[xx + level_width*zz] > 1)? 1.0 : 0.0;
v[6] = 1.0;
}
quads.push_back(q);
}
}
}
void update(float dt){
speed.z -= dt * accel;
if(speed.z < -max_speed) speed.z = -max_speed;
position.z += dt * speed.z;
for(auto& q : quads){
if(q[0][2] > position.z + 4.0) {
for(auto& v : q){
v[2] -= level_length;
}
}
}
if(check() && position.y > -1.1){
// alive
position.y = -1.0;
speed.y = 0.0;
} else {
speed.y -= dt * 4.0;
position.y += dt * speed.y;
}
}
int clamp(int x, int min, int max){
return (x < min) ? min :
((x > max) ? max : x);
}
int position_to_index(Position p){
int amp = level_width/2;
int x = clamp(std::round(p.x), -amp, amp) + amp;
int z = int(std::round(p.z)) % int(level_length);
if(z < 0) z += level_length;
return x + level_width*z;
}
bool check(){
for(auto x : {boundingbox.min.x, boundingbox.max.y}){
for(auto z : {boundingbox.min.z, boundingbox.max.z}){
int index = position_to_index({position.x + x, 0.0, position.z + z});
if(level[index] > 0) return true;
}
}
return false;
}
void draw(GLKMatrix4 projectionMatrix, J::shader& shader){
draw_spaceship(projectionMatrix, shader);
draw_quads(projectionMatrix, shader);
}
void draw_spaceship(GLKMatrix4 projectionMatrix, J::shader& shader){
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
GLKMatrix3 normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
shader.set_uniform("modelViewProjectionMatrix", modelViewProjectionMatrix.m, 0);
shader.set_uniform("normalMatrix", normalMatrix.m, 0);
shader.set_attribute("position", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &quads[0][0][0]);
shader.set_attribute("color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &quads[0][0][3]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, quads.size()*8);
}
void draw_quads(GLKMatrix4 projectionMatrix, J::shader& shader){
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(position.x, position.y, position.z);
GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
GLKMatrix3 normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
shader.set_uniform("modelViewProjectionMatrix", modelViewProjectionMatrix.m, 0);
shader.set_uniform("normalMatrix", normalMatrix.m, 0);
shader.set_attribute("position", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &spaceship[0][0]);
shader.set_attribute("color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &spaceship[0][3]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, spaceship.size());
}
};
#endif