Now it uses Terrain class, but it isn't properly integrated to the infrastructure.
--- a/src/proto2/Physics.cc Sun Nov 30 15:24:33 2008 +0000
+++ b/src/proto2/Physics.cc Sun Nov 30 17:13:16 2008 +0000
@@ -2,6 +2,7 @@
#include "Physics.hh"
#include "Engine.hh"
#include "GameState.hh"
+#include "Terrain.hh"
#include <algorithm>
#include <functional>
@@ -10,16 +11,10 @@
PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
: tick_timer(PHYSICS_TICK_MS), tick_counter(0), dimensions(dimensions),
- gravity(gravity),
- terrain(dimensions.x,
- std::vector<TerrainType>(dimensions.y, DIRT)) {
-
-
- terr = CL_PixelBuffer(MAP_WIDTH, MAP_HEIGHT, 4*MAP_WIDTH, CL_PixelFormat::rgba8888);
-
- generateTerrain(1337);
-
-
+ gravity(gravity) {
+ Engine::log(DEBUG, "Yeah");
+ terrain = Terrain(1337);
+ Engine::log(DEBUG, "Yeah2");
slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
tick_timer.enable();
}
@@ -234,7 +229,7 @@
if(world.getType(newPosition+shape[0]) != EMPTY || (world.getType(newPosition+shape[1]) != EMPTY)
|| (world.getType(newPosition+shape[2]) != EMPTY) || (world.getType(newPosition+shape[3]) != EMPTY)) {
- Engine::log(DEBUG, "physics.update_position") << "didnt hit";
+ // Engine::log(DEBUG, "physics.update_position") << "didnt hit";
// There was error, and there is ground
//newPosition = tmpVector;
} else {
@@ -247,7 +242,7 @@
//TODO: it shouldn't just stop on collision
}
this->position = newPosition;
-
+ // Engine::log(DEBUG, "PhysicsObject.updatePosition") << "Pos: " << this->position;
}
/**
@@ -280,49 +275,7 @@
* Computes hitten wall's normal. Calculated from 3*3 grid
*/
Vector PhysicsWorld::getNormal (Vector hitPoint, Vector prevPoint) {
- // Why doesn't this work
- Vector normal(0,0);
- for (int i = 0; i < 8; i++) {
- if (getType(hitPoint+DIRECTIONS[i]) == EMPTY)
- normal += DIRECTIONS[i];
- }
- return normal;
-
- /*
- // Search free points with bfs and put them to vector
- std::vector<Vector> frees;
- Vector hit(hitPoint);
- Vector pre(prevPoint);
-
-
- assert(hit != prev);
-
- int dirIdx = getDirectionIndex(prev.roundToInt() - hit.roundToInt());
- //float tmp1 = hit.x-prev.x;
- //float tmp2 = hit.y-prev.y;
- // Engine::log(DEBUG, "physics.getNormal ") << dirIdx << " " << tmp1 << " " << tmp2;
-
- for(int i = 1; i <= 2; i++) {
- if(getType(hit+DIRECTIONS[(dirIdx+i) % 8]) == EMPTY)
- frees.push_back(DIRECTIONS[(dirIdx+i) % 8]);
- else
- break;
- }
- for(int i = 1; i <= 2; i++) {
- if(getType(hit+DIRECTIONS[(dirIdx-i+8) % 8]) == EMPTY)
- frees.push_back(DIRECTIONS[(dirIdx-i+8) % 8]);
- else
- break;
- }
- frees.push_back(DIRECTIONS[dirIdx]);
-
- Vector normal(0,0);
- for(unsigned int i = 0; i < frees.size(); i++) {
- normal += frees[i];
- }
- Engine::log(DEBUG, "physics.getNormal ") << "normal: " << normal;
- return normal;
- */
+ return terrain.getNormal(hitPoint);
}
/**
@@ -331,10 +284,12 @@
*/
// TODO Bounce doesnt work kun oikealle tai vasemmalle alaviistoon mennään suoralla (tangentaalinen arvo väärän suuntainen)
void PhysicsObject::bounce (Vector normal) {
- Vector tangent(normal.y, -normal.x);
- Vector tprojection = tangent*(velocity * tangent) / (tangent.length()*tangent.length());
- Vector nprojection = normal*(velocity * normal) / (normal.length()*normal.length());
- velocity = tprojection - nprojection;
+ if (normal.length() != 0) {
+ Vector tangent(normal.y, -normal.x);
+ Vector tprojection = tangent*(velocity * tangent) / (tangent.length()*tangent.length());
+ Vector nprojection = normal*(velocity * normal) / (normal.length()*normal.length());
+ velocity = tprojection - nprojection;
+ }
}
/**
@@ -424,89 +379,14 @@
}
/**
- * simple random map generation
- * first fills whole level with dirt
- * then randomizes circles of empty or rock
- * @param seed - seed number for random number generator
- */
-void PhysicsWorld::generateTerrain(int seed) {
- // generating should use own random number generator, but didn't find easily how that is done
- srand(seed);
-
- // some constants to control random generation
- const int min_range = 25;
- const int max_range = 80;
- const int num = 50;
- const int rock_rarity = 4; // 1 / rock_rarity will be rock circle
-
- // loops for amount of circles
- for(int i = 0; i < num; i++) {
- // information of new circle
- int midx = rand()%(int)dimensions.x;
- int midy = rand()%(int)dimensions.y;
- int range = rand()%(max_range-min_range)+min_range;
-
- // put first circle in the middle of the cave
- // so that we have some area we can certainly spawn into
- if(i == 0) {
- midx = dimensions.x/2;
- midy = dimensions.y/2;
- range = 150;
- }
-
- TerrainType type = EMPTY;
- if(rand()%rock_rarity == 0) {
- type = ROCK;
- }
-
- // loops for every pixel of circle
- for(int x = std::max(0, midx-range); x < std::min((int)dimensions.x, midx+range); x++) {
- for(int y = std::max(0, midy-range); y < std::min((int)dimensions.y, midy+range); y++) {
- //if((x-midx) * (x-midx) + (y-midy) * (y-midy) < range*range) {
- // and sets it to type
- terrain[x][y] = type;
-
- //}
- }
- }
- }
-
- for (int i = 0; i < MAP_WIDTH; i++) {
- for (int j = 0; j < MAP_HEIGHT; j++) {
- CL_Color color;
- switch(getType(i,j)) {
- case EMPTY:
- color = CL_Color(86, 41, 0);
- break;
- case DIRT:
- color = CL_Color(144, 82, 23);
- break;
- case ROCK:
- color = CL_Color(132, 136, 135);
- break;
- default:
- break;
- }
- terr.draw_pixel(i, j, color);
- }
- }
-
-}
-
-/**
* Returns terrainType in given tile. ROCK if tile is out of area
* @param pos - coordinate of tile
*/
TerrainType PhysicsWorld::getType(int x, int y) const {
- if(x < 0 || y < 0 || x >= dimensions.x || y >= dimensions.y) {
- return ROCK;
- }
- return terrain[x][y];
+ return terrain.getType((int32_t)x,(int32_t)y);
}
TerrainType PhysicsWorld::getType(Vector pos) const {
- int x = (int)(pos.x);
- int y = (int)(pos.y);
- return getType(x, y);
+ return terrain.getType(pos.x, pos.y);
}
/**
@@ -515,23 +395,12 @@
* @param r - radius of circle
*/
void PhysicsWorld::removeGround(int x, int y, float r) {
- for(int i = x-(int)r; i < x+r; i++) {
- for(int j = y-(int)r; j < y+r; j++) {
- if(getType(i, j) != ROCK) {
- if((i-x)*(i-x)+(j-y)*(j-y) < r*r) {
- // Safe because getType returns ROCK if tile is out of bounds
- terrain[i][j] = EMPTY;
- terr.draw_pixel(i, j, CL_Color(86, 41, 0));
- }
- }
- }
- }
+ terrain.removeGround(Vector(x,y), r);
}
void PhysicsWorld::removeGround(Vector pos, float r) {
- removeGround((int)pos.x, (int)pos.y, r);
+ terrain.removeGround(pos, r);
}
void PhysicsWorld::drawTerrain(CL_GraphicContext *gc) {
- CL_Surface surf(terr);
- surf.draw(0, 0, gc);
+ terrain.draw(gc);
}
--- a/src/proto2/Physics.hh Sun Nov 30 15:24:33 2008 +0000
+++ b/src/proto2/Physics.hh Sun Nov 30 17:13:16 2008 +0000
@@ -8,6 +8,7 @@
#include "Vector.hh"
#include "Config.hh"
+#include "Terrain.hh"
// Forward declares
class PhysicsWorld;
@@ -22,13 +23,13 @@
typedef Vector Force;
// TODO: Random definitions. Should these be somewhere else?
-enum TerrainType {EMPTY, DIRT, ROCK};
+//enum TerrainType {EMPTY, DIRT, ROCK};
// Yeah?!?!?! Atleast this could be documented. Contains vectors
// presenting all the 8 directions in a square grid?
-const Vector DIRECTIONS[] = { Vector(0,-1), Vector(1,-1), Vector(1,0),
- Vector(1,1), Vector(0,1), Vector(-1,1),
- Vector(-1,0), Vector(-1,-1) };
+//const Vector DIRECTIONS[] = { Vector(0,-1), Vector(1,-1), Vector(1,0),
+// Vector(1,1), Vector(0,1), Vector(-1,1),
+// Vector(-1,0), Vector(-1,-1) };
/**
@@ -42,6 +43,8 @@
CL_Timer tick_timer;
uint32_t tick_counter;
+ Terrain terrain;
+
protected:
//std::vector<PlayerObject*> players;
//std::vector<ProjectileObject*> projectiles;
@@ -56,10 +59,7 @@
Vector dimensions;
Vector gravity;
- // TODO: Should this be it's own class?
- std::vector<std::vector<TerrainType> > terrain;
- CL_PixelBuffer terr;
- // CL_Surface surf;
+
public:
// TODO: Replace addObject with these?
--- a/src/proto2/Terrain.cc Sun Nov 30 15:24:33 2008 +0000
+++ b/src/proto2/Terrain.cc Sun Nov 30 17:13:16 2008 +0000
@@ -1,11 +1,13 @@
#include "Terrain.hh"
+#include "Engine.hh"
#include <cmath>
#include <algorithm>
#include <ClanLib/display.h>
Terrain::Terrain() {}
-Terrain::Terrain(const int &seed) {
+Terrain::Terrain(const int &seed)
+ : terrain(MAP_WIDTH, std::vector<TerrainType>(MAP_HEIGHT, DIRT)){
this->generateTerrain(seed);
}
Terrain::Terrain(const Terrain &t) {
@@ -38,16 +40,16 @@
}
}
-Vector Terrain::getPixelLocation(Vector point) {
+Vector Terrain::getPixelLocation(Vector point) const{
return Vector(scale(point.x),
scale(point.y));
}
-uint16_t Terrain::scale(float x) {
+uint16_t Terrain::scale(float x) const {
return (uint16_t)round(x/MAP_SCALE);
}
-TerrainType Terrain::getType(uint16_t x, uint16_t y) {
+TerrainType Terrain::getType(int32_t x, int32_t y) const {
if ((x < 0) || (y < 0) ||(x >= MAP_WIDTH) || (y >= MAP_HEIGHT)) {
return ROCK;
}
@@ -78,7 +80,7 @@
}
uint16_t dx = e.x - b.x;
uint16_t dy = abs(e.y - b.y);
- uint16_t err = dx/2;
+ int32_t err = dx/2;
uint16_t ystep;
uint16_t y = b.y;
// Is the line ascending or descending
@@ -104,19 +106,19 @@
return false; // No Collision
}
-void Terrain::removeGround(const Vector &pos, const float radius) {
+void Terrain::removeGround(const Vector &pos, const float &radius) {
// TODO: Implement. Some circle algoritmh should be usefull here,
// though the current impelementation doesn't seem too bad either.
Vector mid = getPixelLocation(pos);
uint16_t r = scale(radius);
for (uint16_t i = mid.x-r; i < mid.x+r; i++) {
- for (uint_16_t j = mid.y-r; j < mid.y+r; j++) {
+ for (uint16_t j = mid.y-r; j < mid.y+r; j++) {
if (getType(i, j) != ROCK) { // getType returns ROCK if
// out of bounds
if ((i-mid.x)*(i-mid.x)+(j-mid.y)*(j-mid.y) < r*r) {
terrain[i][j] = EMPTY;
- terr.draw_pixel(i, j, COLOR_EMPTY);
+ pixbuf.draw_pixel(i, j, COLOR_EMPTY);
}
}
}
@@ -132,6 +134,7 @@
normal += DIRECTIONS[i];
}
}
+ Engine::log(DEBUG, "Terrain.getNormal") << "Normal: " << normal;
return normal;
}
@@ -168,17 +171,18 @@
// Loops for every pixel of the cirlcle (or square as it seems
// now)
for (int x = std::max(0, midx-range);
- x < std::min(MAP_WIDTH, midx+range);
+ x < std::min((int32_t)MAP_WIDTH, midx+range);
x++) {
for (int y = std::max(0, midy-range);
- y < std::min((int)MAP_HEIGHT, midy+range);
+ y < std::min((int32_t)MAP_HEIGHT, midy+range);
y++) {
terrain[x][y] = type;
- }
+ }
+
}
-
+
}
-
+
this->generatePixelBuffer();
}
@@ -186,3 +190,7 @@
CL_Surface surf(this->pixbuf);
surf.draw(0,0,gc);
}
+
+std::vector<std::vector<TerrainType> > Terrain::getTerrain() const {
+ return terrain;
+}
--- a/src/proto2/Terrain.hh Sun Nov 30 15:24:33 2008 +0000
+++ b/src/proto2/Terrain.hh Sun Nov 30 17:13:16 2008 +0000
@@ -48,7 +48,7 @@
* @param point Point in "real" units
* @return Int vector
*/
- Vector getPixelLocation(Vector point);
+ Vector getPixelLocation(Vector point) const;
/**
* Scale parameter to "pixels"
@@ -56,8 +56,11 @@
* @param x Scaled value
* @return Corresponding value in pixels
*/
- uint16_t scale(float x);
+ uint16_t scale(float x) const;
+ public:
+
+ // TODO: This should be private.
/**
* Return the type of terrain at given position. Returns ROCK if
* given point is not inside terrain area.
@@ -66,9 +69,8 @@
* @param y Y coordinate
* @return Terrain type
*/
- TerrainType getType(uint16_t x, uint16_t y);
+ TerrainType getType(int32_t x, int32_t y) const;
-public:
/**
* Constructor.
*
@@ -92,7 +94,7 @@
/**
* Destructor
*/
- ~Terrain();
+ ~Terrain() {}
/**
* Check if given point has some terrain.
@@ -114,7 +116,7 @@
* @param pos Circle center
* @param r Circle radius
*/
- void removeGround(Vector pos, float r);
+ void removeGround(const Vector &pos, const float &r);
/**
* Return normal for the given point.
@@ -136,7 +138,7 @@
*
* @param gc CL_GraphicContext
*/
- void draw(CL_GraphicContext *gc) const;
+ void draw(CL_GraphicContext *gc);
/**
* Draw part of the terrain for given graphiscontext.
*
@@ -144,7 +146,7 @@
* @param center Center of the rectangle drawn.
* @param dimension Dimensions of the rectangle.
*/
- void draw(CL_GraphicContext &gc, Vector center, Vector dimensions);
+ //void draw(CL_GraphicContext &gc, Vector center, Vector dimensions);
/**
* Set terrain.