202 lines
5 KiB
Objective-C
202 lines
5 KiB
Objective-C
//
|
|
// 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
|