add PixelDimension/PixelCoordinate types, convert Terrain to use them, and convert/clean up drawing code
--- a/src/Config.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Config.hh Sun Dec 07 20:07:28 2008 +0000
@@ -32,6 +32,7 @@
const float PLAYER_AIM_MAX = KG_PI/2;
const float PLAYER_INITIAL_X = 400.0;
const float PLAYER_INITIAL_Y = 300.0;
+const float PLAYER_CROSSHAIR_LENGTH = 10.0;
const float CROSSHAIR_ANGLE_SPEED = PI/40;
const float PLAYER_MAX_SPEED = 43;
--- a/src/GameState.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/GameState.cc Sun Dec 07 20:07:28 2008 +0000
@@ -3,7 +3,11 @@
#include "Engine.hh"
#include "Config.hh"
-GameState::GameState (void) : local_player(NULL), world(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT)) { }
+GameState::GameState (void) :
+ local_player(NULL), world(Vector(0, MAP_GRAVITY), Vector(MAP_WIDTH, MAP_HEIGHT))
+{
+
+}
void GameState::addProjectile (Projectile *projectile) {
projectiles.push_back(projectile);
@@ -31,9 +35,10 @@
}
void GameState::draw(Graphics *g, bool displayWeapon) {
- Vector camera = local_player->getPosition()-Vector(800/2, 600/2);
+ PixelCoordinate camera = world.getPixelCoordinate(local_player->getPosition()) - world.getDimensions() / 2;
+
// Draw world/terrain
- world.draw(g->get_gc(), camera);
+ world.draw(g, camera);
// Draw players
for (std::list<Player*>::iterator it = player_list.begin(); it != player_list.end(); it++) {
--- a/src/Network/Client.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Network/Client.cc Sun Dec 07 20:07:28 2008 +0000
@@ -135,7 +135,7 @@
int flags = pkt.read_uint8();
float aim = pkt.read_float32();
- Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", position=" << position << ", velocity=" << velocity << ", aim=" << aim << ", [" << flags << "]";
+// Engine::log(INFO, "client_player.on_position") << "obj=" << obj << ", position=" << position << ", velocity=" << velocity << ", aim=" << aim << ", [" << flags << "]";
// just update...
updatePhysics(position, velocity, flags & NETWORK_PHYSICS_INAIR, flags & NETWORK_PHYSICS_FACE_RIGHT, aim);
--- a/src/Network/Server.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Network/Server.cc Sun Dec 07 20:07:28 2008 +0000
@@ -174,7 +174,7 @@
// read packet
PlayerInput input = pkt.read_uint16();
- Engine::log(INFO, "server_player.on_input") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
+// Engine::log(INFO, "server_player.on_input") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
// apply input
handleInput(input);
@@ -220,7 +220,7 @@
pkt.write_uint8(flags);
pkt.write_float32(aim);
- Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity << " [" << flags << "]";
+// Engine::log(INFO, "server_player.send_position_update") << "obj=" << obj << " -> " << position << "+" << velocity << " [" << flags << "]";
obj.send_all(NETMSG_PLAYER_POSITION, pkt, false);
}
--- a/src/PhysicsObject.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/PhysicsObject.hh Sun Dec 07 20:07:28 2008 +0000
@@ -162,7 +162,14 @@
*
* @return Position vector
*/
- Vector getPosition();
+ Vector getPosition (void);
+
+ /**
+ * Get current object screen coordinates
+ *
+ * @return PixelCoordinate position
+ */
+ PixelCoordinate getCoordinate (void);
/**
* Get current object velocity.
--- a/src/PhysicsWorld.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/PhysicsWorld.cc Sun Dec 07 20:07:28 2008 +0000
@@ -5,7 +5,7 @@
#include <functional>
PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions) :
- Terrain(1337), tick_timer(PHYSICS_TICK_MS), dimensions(dimensions), gravity(gravity)
+ Terrain(dimensions.x, dimensions.y, 1337), tick_timer(PHYSICS_TICK_MS), dimensions(dimensions), gravity(gravity)
{
slots.connect(tick_timer.sig_tick(), this, &PhysicsWorld::tick);
tick_timer.start();
@@ -20,8 +20,8 @@
}
void PhysicsWorld::tick (TimeMS tick_length) {
+ // tick each object in turn
for (std::list<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
-// Engine::log(DEBUG, "PhysicsWorld.tick") << (*i);
(*i)->tick(tick_length);
}
--- a/src/PhysicsWorld.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/PhysicsWorld.hh Sun Dec 07 20:07:28 2008 +0000
@@ -33,7 +33,6 @@
// Contains connections between signals and slots
CL_SlotContainer slots;
- // TODO: Should these be somewhere else?
Vector dimensions;
Vector gravity;
--- a/src/Player.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Player.cc Sun Dec 07 20:07:28 2008 +0000
@@ -181,12 +181,12 @@
return weapons[selectedWeapon % weapons.size()];
}
-void Player::draw (Graphics *g, Vector camera) {
+void Player::draw (Graphics *g, PixelCoordinate camera) {
CL_GraphicContext *gc = g->get_gc();
- int cx = (int)camera.x, cy = (int)camera.y;
-
- int aim_img_idx = (int)((1 - (getAim()+KG_PI/2)/KG_PI)*img_num_aim);
- int step_img_idx = animation_step%img_num_step;
+
+ // animation indexes
+ int aim_img_idx = (int)((1 - (getAim() + KG_PI / 2) / KG_PI) * img_num_aim);
+ int step_img_idx = animation_step % img_num_step;
// load skin image if not yet loaded
if (!skin_loaded) {
@@ -194,46 +194,40 @@
skin_loaded = true;
}
- // XXX: this logic looks weird
- CL_Rectf destination(position.x - img_width/2 -cx, position.y - img_height/2 -cy, position.x + img_width/2 -cx, position.y + img_height/2 -cy);
-
- if (!getFacing()) {
- destination = CL_Rect(position.x + img_width/2 -cx, position.y - img_height/2 -cy, position.x - img_width/2 -cx, position.y + img_height/2 -cy);
- }
-
- skin_surface.draw_subpixel(
- CL_Rectf(
- step_img_idx * img_width,
- aim_img_idx * img_height,
- (1 + step_img_idx) * img_width,
- (aim_img_idx + 1) * img_height
- ),
- destination, gc
+ // calulate where to draw the worm
+ CL_Rectf destination(
+ position.x + (getFacing() ? -1 : 1) * img_width / 2 - camera.x,
+ position.y - img_height / 2 - camera.y,
+ position.x + (getFacing() ? 1 : -1) * img_width / 2 - camera.x,
+ position.y + img_height / 2 - camera.y
);
- const uint16_t chlen = 10;
- int x = position.x -cx;
- int y = position.y -cy;
+ // draw the correct animation frame from the skin
+ skin_surface.draw_subpixel(
+ CL_Rectf(
+ step_img_idx * img_width,
+ aim_img_idx * img_height,
+ (1 + step_img_idx) * img_width,
+ (aim_img_idx + 1) * img_height
+ ), destination, gc
+ );
- // draw "crosshair"
- if (facingRight) {
- gc->draw_line(x + std::cos(aim)*chlen/2,
- y - std::sin(aim)*chlen/2,
- x + std::cos(aim)*chlen,
- y - std::sin(aim)*chlen,
- CL_Color::black);
- } else {
- gc->draw_line(x - std::cos(aim)*chlen/2,
- y - std::sin(aim)*chlen/2,
- x - std::cos(aim)*chlen,
- y - std::sin(aim)*chlen,
- CL_Color::black);
- }
+ // draw "crosshair", a half-line from our position to 10px away
+ Vector crosshair = getDirection() * PLAYER_CROSSHAIR_LENGTH;
+ PixelCoordinate aim_start = state.world.getPixelCoordinate(
+ position + crosshair / 2) - camera;
+
+ PixelCoordinate aim_end = state.world.getPixelCoordinate(
+ position + crosshair) - camera;
+
+ gc->draw_line(aim_start.x, aim_start.y, aim_end.x, aim_end.y, CL_Color::black);
+
+ // draw rope
rope.draw(g, camera);
}
-void LocalPlayer::draw (Graphics *g, bool displayWeapon, Vector camera) {
+void LocalPlayer::draw (Graphics *g, bool displayWeapon, PixelCoordinate camera) {
// superclass draw
Player::draw(g, camera);
@@ -241,9 +235,12 @@
if (displayWeapon && getCurrentWeapon()) {
const std::string weaponName = getCurrentWeapon()->getName();
+ const PixelCoordinate pc = state.world.getPixelCoordinate(position) - camera;
+
+ // XXX: fix magic constants once we know how big the worm is
g->getSimpleFont().draw(
- position.x - camera.x - g->getSimpleFont().get_width(weaponName) / 2,
- position.y - camera.y - 20,
+ pc.x - g->getSimpleFont().get_width(weaponName) / 2,
+ pc.y - 20,
weaponName,
g->get_gc()
);
--- a/src/Player.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Player.hh Sun Dec 07 20:07:28 2008 +0000
@@ -71,7 +71,7 @@
*/
static bool skin_loaded;
static CL_Surface skin_surface;
- virtual void draw (Graphics *g, Vector camera = Vector(0, 0));
+ virtual void draw (Graphics *g, PixelCoordinate camera);
};
class LocalPlayer : public virtual Player {
@@ -97,7 +97,7 @@
/*
* As Player, but also draws the current weapon name if displayWeapon
*/
- virtual void draw (Graphics *g, bool displayWeapon, Vector camera);
+ virtual void draw (Graphics *g, bool displayWeapon, PixelCoordinate camera);
};
class RemotePlayer : public virtual Player {
--- a/src/Projectile.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Projectile.cc Sun Dec 07 20:07:28 2008 +0000
@@ -13,7 +13,6 @@
shape[3] = Vector(1, -1);
setShape(shape);
- target_visible = false;
collision_elasticity = 0.9; // = shotType.elasticity
state.addProjectile(this);
}
@@ -43,36 +42,20 @@
PhysicsObject::tick(dt);
}
-void Projectile::draw(Graphics *g, Vector cam) const {
+void Projectile::draw(Graphics *g, PixelCoordinate camera) const {
CL_GraphicContext *gc = g->get_gc();
if (visible) {
-
+ PixelCoordinate pos = state.world.getPixelCoordinate(position) - camera;
+
CL_Quad projectile(
- (int)((position).x+1-cam.x), (int)((position).y+1-cam.y),
- (int)((position).x-1-cam.x), (int)((position).y+1-cam.y),
- (int)((position).x+1-cam.x), (int)((position).y-1-cam.y),
- (int)((position).x-1-cam.x), (int)((position).y-1-cam.y)
- );
+ pos.x + 1, pos.y + 1,
+ pos.x - 1, pos.y + 1,
+ pos.x + 1, pos.y - 1,
+ pos.x - 1, pos.y - 1
+ );
gc->fill_quad(projectile, CL_Color::green);
-
- const uint16_t chlen = 10;
- int x = projectile.center().x -cam.x;
- int y = projectile.center().y -cam.y;
- if (target_visible) {
- if (facingRight) {
- gc->draw_line(x, y,
- x + std::cos(aim)*chlen,
- y - std::sin(aim)*chlen,
- CL_Color::black);
- } else {
- gc->draw_line(x, y,
- x - std::cos(aim)*chlen,
- y - std::sin(aim)*chlen,
- CL_Color::black);
- }
- }
}
}
--- a/src/Projectile.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Projectile.hh Sun Dec 07 20:07:28 2008 +0000
@@ -12,7 +12,6 @@
protected:
GameState &state;
bool visible;
- bool target_visible;
float radius;
public:
@@ -22,7 +21,7 @@
Projectile (GameState &state, Vector position, Vector velocity, bool visible, float radius, TickCount age=1000000000);
virtual ~Projectile (void);
- virtual void draw (Graphics *g, Vector camera = Vector(0, 0)) const;
+ virtual void draw (Graphics *g, PixelCoordinate camera) const;
protected:
/**
--- a/src/Rope.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Rope.cc Sun Dec 07 20:07:28 2008 +0000
@@ -120,13 +120,16 @@
return 0;
}
-void Rope::draw (Graphics *g, Vector cam) const {
+void Rope::draw (Graphics *g, PixelCoordinate camera) {
if (state == ROPE_FOLDED)
return;
+ PixelCoordinate player_pos = world.getPixelCoordinate(player.getPosition()) - camera;
+ PixelCoordinate self_pos = world.getPixelCoordinate(getPosition()) - camera;
+
g->get_gc()->draw_line(
- player.getPosition().x-cam.x, player.getPosition().y-cam.y,
- position.x-cam.x, position.y-cam.y,
+ player_pos.x, player_pos.y,
+ self_pos.x, self_pos.y,
CL_Color::black
);
}
--- a/src/Rope.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Rope.hh Sun Dec 07 20:07:28 2008 +0000
@@ -77,7 +77,7 @@
/*
* Just draws it
*/
- virtual void draw (Graphics *c, Vector camera = Vector(0, 0)) const;
+ virtual void draw (Graphics *c, PixelCoordinate camera);
};
#endif
--- a/src/Terrain.cc Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Terrain.cc Sun Dec 07 20:07:28 2008 +0000
@@ -1,4 +1,5 @@
#include "Terrain.hh"
+#include "Graphics.hh"
#include "Engine.hh"
#include <cmath>
@@ -6,17 +7,30 @@
#include <algorithm>
#include <ClanLib/display.h>
-Terrain::Terrain() {}
-Terrain::Terrain(const int &seed)
- : terrain(MAP_WIDTH, std::vector<TerrainType>(MAP_HEIGHT, DIRT)){
- this->generateTerrain(seed);
-}
-Terrain::Terrain(const Terrain &t) {
- this->terrain = t.getTerrain();
- this->generatePixelBuffer();
+Terrain::Terrain (void) :
+ map_width(0), map_height(0)
+{
}
-void fractal_step(std::vector<double>& land, int size, double str, int dist) {
+Terrain::Terrain (PixelDimension map_width, PixelDimension map_height, int seed) :
+ map_width(map_width), map_height(map_height), terrain(map_width, std::vector<TerrainType>(map_height, TERRAIN_DIRT))
+{
+ generateTerrain(seed);
+}
+
+Terrain::Terrain (const Terrain &t)
+{
+ map_width = t.map_width;
+ map_height = t.map_height;
+ terrain = t.terrain;
+
+ generatePixelBuffer();
+}
+
+/*
+ * Texture generation util functions
+ */
+static void fractal_step(std::vector<double>& land, int size, double str, int dist) {
for(int i = 0; i < size; i += dist*2) {
for(int j = dist; j < size; j += dist*2) {
double sum = 0;
@@ -38,7 +52,8 @@
}
}
}
-void fractal_diamond(std::vector<double>& land, int size, double str, int dist) {
+
+static void fractal_diamond(std::vector<double>& land, int size, double str, int dist) {
for(int i = dist; i < size; i += dist*2) {
for(int j = dist; j < size; j += dist*2) {
double sum = 0;
@@ -54,7 +69,7 @@
/**
* Algorithm read from http://www.gameprogrammer.com/fractal.html
*/
-void Terrain::generate_texture() {
+void Terrain::generate_texture (void) {
int texturesize = 128;
texture = std::vector<std::vector<int> >(texturesize, std::vector<int>(texturesize));
std::vector<double> land(texture.size()*texture.size());
@@ -85,27 +100,31 @@
* Changes color depending on x and y values
* x and y should be valid coordinates (not outside)
*/
-void Terrain::noisifyPixel(CL_Color& color, int x, int y) {
- int tx = x%texture.size();
- int ty = y%texture[0].size();
+void Terrain::noisifyPixel(CL_Color& color, PixelCoordinate pc) {
+ int tx = pc.x % texture.size();
+ int ty = pc.y % texture[0].size();
int red = color.get_red();
int green = color.get_green();
int blue = color.get_blue();
- red += texture[tx][ty]/8-16;
- green += texture[tx][ty]/8-16;
- blue += texture[tx][ty]/8-16;
- if(red < 0)
+
+ red += texture[tx][ty] / 8 - 16;
+ green += texture[tx][ty] / 8 - 16;
+ blue += texture[tx][ty] / 8 - 16;
+
+ if (red < 0)
red = 0;
- if(red >= 256)
+ else if (red >= 256)
red = 255;
- if(green < 0)
+
+ if (green < 0)
green = 0;
- if(blue >= 256)
+ else if (green >= 256)
+ green = 255;
+
+ if (blue < 0)
+ blue = 0;
+ else if (blue >= 256)
blue = 255;
- if(blue < 0)
- blue = 0;
- if(green >= 256)
- green = 255;
color = CL_Color(red, green, blue);
}
@@ -113,137 +132,156 @@
/**
* Sets to color the correct color of pixel in (x,y)
*/
-void Terrain::loadPixelColor(CL_Color& color, int x, int y) {
- if ((x < 0) || (y < 0) ||(x >= MAP_WIDTH) || (y >= MAP_HEIGHT)) {
+void Terrain::loadPixelColor(CL_Color& color, PixelCoordinate pc) {
+ if ((pc.x < 0) || (pc.y < 0) || (pc.x >= map_width) || (pc.y >= map_height)) {
color = CL_Color(0, 0, 0);
return;
}
- switch(terrain[x][y]) {
- case EMPTY:
+
+ switch (terrain[pc.x][pc.y]) {
+ case TERRAIN_EMPTY:
color = COLOR_EMPTY;
- noisifyPixel(color, x, y);
break;
- case DIRT:
+
+ case TERRAIN_DIRT:
color = COLOR_DIRT;
- noisifyPixel(color, x, y);
break;
- case ROCK:
+
+ case TERRAIN_ROCK:
color = COLOR_ROCK;
- noisifyPixel(color, x, y);
break;
}
+
+ noisifyPixel(color, pc);
}
-void Terrain::generatePixelBuffer() {
+void Terrain::generatePixelBuffer (void) {
+ // initialze texture
generate_texture();
- this->pixbuf = CL_PixelBuffer(MAP_WIDTH, MAP_HEIGHT, 4*MAP_WIDTH,
- CL_PixelFormat::rgba8888);
+
+ // create pixel buffer
+ pixbuf = CL_PixelBuffer(map_width, map_height, 4 * map_width, CL_PixelFormat::rgba8888);
CL_Color color;
- for (uint16_t i = 0; i < MAP_WIDTH; i++) {
- for (uint16_t j = 0; j < MAP_HEIGHT; j++) {
- switch(terrain[i][j]) {
- case EMPTY:
- color = COLOR_EMPTY;
- break;
- case DIRT:
- color = COLOR_DIRT;
- break;
- case ROCK:
- color = COLOR_ROCK;
- break;
- default: // TODO: Shouldn't be here.
- break;
- }
- loadPixelColor(color, i, j);
- this->pixbuf.draw_pixel(i, j, color);
+
+ for (PixelDimension x = 0; x < map_width; x++) {
+ for (PixelDimension y = 0; y < map_height; y++) {
+ PixelCoordinate pc(x, y);
+
+ loadPixelColor(color, pc);
+
+ pixbuf.draw_pixel(pc.x, pc.y, color);
}
}
}
-Vector Terrain::getPixelLocation(Vector point) const{
- return Vector(scale(point.x),
- scale(point.y));
-}
-
-uint16_t Terrain::scale(float x) const {
- return (uint16_t)(x/MAP_SCALE);
+PixelCoordinate Terrain::getPixelCoordinate (Vector point) const {
+ return PixelCoordinate(point.x, point.y);
}
-TerrainType Terrain::getType(int32_t x, int32_t y) const {
- if ((x < 0) || (y < 0) ||(x >= MAP_WIDTH) || (y >= MAP_HEIGHT)) {
- return ROCK;
- }
- return terrain[x][y];
-}
-TerrainType Terrain::getType(Vector point) const {
- return getType((int32_t)point.x, (int32_t)point.y);
+PixelCoordinate Terrain::getDimensions (void) const {
+ return PixelCoordinate(map_width, map_height);
}
-bool Terrain::collides(const Vector &point) const {
- return (getType(point) != EMPTY);
+TerrainType Terrain::getType (PixelDimension px, PixelDimension py) const {
+ if ((px < 0) || (py < 0) ||(px >= map_width) || (py >= map_height))
+ return TERRAIN_ROCK;
+
+ return terrain[px][py];
}
-bool Terrain::collides(const Vector &begin, const Vector &end) const {
+TerrainType Terrain::getType (PixelCoordinate pc) const {
+ return getType(pc.x, pc.y);
+}
+
+TerrainType Terrain::getType (Vector point) const {
+ return getType((PixelDimension) point.x, (PixelDimension) point.y);
+}
+
+bool Terrain::collides (const Vector &point) const {
+ return (getType(point) != TERRAIN_EMPTY);
+}
+
+bool Terrain::collides (const Vector &begin, const Vector &end) const {
// TODO: Maybe we should have another function prototype that also
// returns the point where we collided.
// We'll use Bresenhams line algorithm to go trough all the
// "pixels" of the line.
- Vector b = getPixelLocation(begin);
- Vector e = getPixelLocation(end);
+ PixelCoordinate b = getPixelCoordinate(begin);
+ PixelCoordinate e = getPixelCoordinate(end);
bool steep = (abs(e.y - b.y) > abs(e.x - b.x)); // k > 1
- if (steep) { // Line is steep -> swap x and y coordinates
+
+ if (steep) {
+ // Line is steep -> swap x and y coordinates
std::swap(b.x, b.y);
std::swap(e.x, e.y);
}
- if (b.x > e.x) { // Line goes down -> make it go up
+
+ if (b.x > e.x) {
+ // Line goes down -> make it go up
std::swap(b, e);
}
- uint16_t dx = e.x - b.x;
- uint16_t dy = abs(e.y - b.y);
- int32_t err = dx/2;
- uint16_t ystep;
- uint16_t y = b.y;
+
+ PixelDimension dx = e.x - b.x, dy = abs(e.y - b.y);
+ PixelDimension err = dx / 2;
+ PixelDimension ystep, y = b.y;
+
// Is the line ascending or descending
- if (b.y < e.y) ystep = 1;
- else ystep = -1;
+ if (b.y < e.y)
+ ystep = 1;
+
+ else
+ ystep = -1;
+
// Go trough the line
- for (uint16_t x = b.x; x <= e.x; x++) {
- if (steep) { // X and Y coordinates must be switched if steep
- if (getType(y,x) != EMPTY) { // Collision!
+ for (PixelDimension x = b.x; x <= e.x; x++) {
+ if (steep) {
+ // X and Y coordinates must be switched if steep
+ if (getType(y, x) != TERRAIN_EMPTY) {
+ // Collision!
return true;
}
} else {
- if (getType(x,y) != EMPTY) { // Collision!
+ if (getType(x, y) != TERRAIN_EMPTY) {
+ // Collision!
return true;
}
}
+
err = err - dy;
- if (err < 0) { // Check if we want to make an ystep
+
+ if (err < 0) {
+ // Check if we want to make an ystep
y = y + ystep;
err = err + dx;
}
}
+
return false; // No Collision
}
-void Terrain::removeGround(const Vector &pos, const float &radius) {
+void Terrain::removeGround (const Vector &pos, 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 (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;
- CL_Color color(0, 0, 0);
- loadPixelColor(color, i, j);
- pixbuf.draw_pixel(i, j, color);
+ PixelCoordinate mid = getPixelCoordinate(pos);
+ PixelDimension r = radius;
+
+ for (PixelDimension i = mid.x - r; i < mid.x + r; i++) {
+ for (PixelDimension j = mid.y-r; j < mid.y+r; j++) {
+ PixelCoordinate pc(i, j);
+
+ if (getType(pc) != TERRAIN_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] = TERRAIN_EMPTY;
+
+ CL_Color color;
+ loadPixelColor(color, pc);
+ pixbuf.draw_pixel(pc.x, pc.y, color);
}
}
}
@@ -254,25 +292,26 @@
* Gets the index of the given coordinate direction
* referring to the DIRECTIONS table in Physics.hh
*/
-int getDirectionIndex (Vector direction) {
+static int getDirectionIndex (Vector direction) {
Vector dir = direction.roundToInt();
if(dir.x == 0 && dir.y == -1) {
return 0;
- } else if(dir.x == 1 && dir.y == -1) {
+ } else if (dir.x == 1 && dir.y == -1) {
return 1;
- } else if(dir.x == 1 && dir.y == 0) {
+ } else if (dir.x == 1 && dir.y == 0) {
return 2;
- } else if(dir.x == 1 && dir.y == 1) {
+ } else if (dir.x == 1 && dir.y == 1) {
return 3;
- } else if(dir.x == 0 && dir.y == 1) {
+ } else if (dir.x == 0 && dir.y == 1) {
return 4;
- } else if(dir.x == -1 && dir.y == 1) {
+ } else if (dir.x == -1 && dir.y == 1) {
return 5;
- } else if(dir.x == -1 && dir.y == 0) {
+ } else if (dir.x == -1 && dir.y == 0) {
return 6;
- } else if(dir.x == -1 && dir.y == -1) {
+ } else if (dir.x == -1 && dir.y == -1) {
return 7;
}
+
Engine::log(DEBUG, "Terrain.getDirectionIndex ") << "invalid direction: " << direction;
return 0;
}
@@ -283,7 +322,7 @@
* @param prevPoint - pixel where we are when we collide
*/
Vector Terrain::getNormal(Vector point, Vector prevPoint) const {
- Vector p = getPixelLocation(point);
+ PixelCoordinate p = getPixelCoordinate(point);
assert(point != prevPoint);
@@ -291,54 +330,44 @@
// These two must be rounded separately
int dirIdx = getDirectionIndex(prevPoint.roundToInt() - point.roundToInt());
-// dirIdx = (dirIdx+4)%8;
normal += DIRECTIONS[dirIdx];
+
for (int i = 1; i <= 2; i++) {
- if(getType(point + DIRECTIONS[(dirIdx+i+8)%8]) == EMPTY) {
+ if (getType(point + DIRECTIONS[(dirIdx+i+8)%8]) == TERRAIN_EMPTY) {
normal += DIRECTIONS[(dirIdx+i+8)%8];
}
}
+
for (int i = 1; i <= 2; i++) {
- if(getType(point + DIRECTIONS[(dirIdx-i+8)%8]) == EMPTY) {
+ if (getType(point + DIRECTIONS[(dirIdx-i+8)%8]) == TERRAIN_EMPTY) {
normal += DIRECTIONS[(dirIdx-i+8)%8];
}
}
- if (getType(point) == EMPTY || getType(prevPoint) != EMPTY) {
+ if (getType(point) == TERRAIN_EMPTY || getType(prevPoint) != TERRAIN_EMPTY) {
Engine::log(DEBUG, "Physics.getNormal ") << "logic ground error";
}
-
-// for (int i = 0; i < 8; i++) {
-// if (getType(p.x+DIRECTIONS[i].x, p.y+DIRECTIONS[i].y) == EMPTY) {
-// normal += DIRECTIONS[i];
-// }
-// }
-
-
- // Special cases
- /* Vector tmp = direction(direction(prevPoint-point) + direction(normal));
- Engine::log(DEBUG, "Terrain.getNormal") << "tmp: " << tmp;
- if (normal.length() == 0 || (tmp.x != 0 && tmp.y != 0 && getType(tmp.x, tmp.y) != EMPTY))
- normal = prevPoint - point; // Direct hit
- */
-// Engine::log(DEBUG, "Terrain.getNormal") << "Normal: " << normal;
return normal;
- return Vector(0,-1);
}
-Vector direction(const Vector &v) {
+// XXX: weird vectors
+Vector direction (const Vector &v) {
Vector tmp(v);
- if (tmp.length() > 0) tmp /= tmp.length();
+
+ if (tmp.length() > 0)
+ tmp /= tmp.length();
+
tmp.x = (uint16_t)(tmp.x);
tmp.y = (uint16_t)(tmp.y);
+
return tmp;
}
// TODO: This could better :)
// TODO: And this need some cleaning :)
-void Terrain::generateTerrain(int seed) {
+void Terrain::generateTerrain (int seed) {
srand(seed); // Set random number generator seed.
// Some constants to control random generation
@@ -350,48 +379,49 @@
// Generate circles (or whatever)
for (int i = 0; i < num; i++) {
// Random generate circle attributes
- int midx = rand()%MAP_WIDTH;
- int midy = rand()%MAP_HEIGHT;
+ PixelCoordinate mid(rand() % map_width, rand() % map_width);
+
int range = rand()%(max_range-min_range)+min_range;
// Make sure that there's a circle in the midle of the cave
if (i == 0) {
- midx = MAP_WIDTH/2;
- midy = MAP_WIDTH/2;
+ mid.x = map_width / 2;
+ mid.y = map_height / 2;
range = 150;
}
- TerrainType type = EMPTY;
- if (rand()%rock_rarity == 0) {
- type = ROCK;
+ TerrainType type = TERRAIN_EMPTY;
+
+ if (rand() % rock_rarity == 0) {
+ type = TERRAIN_ROCK;
}
// Loops for every pixel of the cirlcle (or square as it seems
// now)
- for (int x = std::max(0, midx-range);
- x < std::min((int32_t)MAP_WIDTH, midx+range);
- x++) {
- for (int y = std::max(0, midy-range);
- y < std::min((int32_t)MAP_HEIGHT, midy+range);
- y++) {
-
- //terrain[x][y] = type;
-
- if ((x-midx)*(x-midx)+(y-midy)*(y-midy) < range*range) {
+ for (
+ PixelDimension x = std::max((PixelDimension) 0, mid.x - range);
+ x < std::min(map_width, mid.x + range);
+ x++
+ ) {
+ for (
+ PixelDimension y = std::max((PixelDimension) 0, mid.y - range);
+ y < std::min(map_height, mid.y + range);
+ y++
+ ) {
+ if ((x - mid.x) * (x - mid.x) + (y - mid.y) * (y - mid.y) < range * range) {
terrain[x][y] = type;
}
}
-
}
-
}
+ // regenerate pixel buffer
this->generatePixelBuffer();
}
-void Terrain::draw(CL_GraphicContext *gc, Vector camera) {
- CL_Surface surf(this->pixbuf);
- surf.draw((int)-camera.x, (int)-camera.y ,gc);
+void Terrain::draw (Graphics *g, PixelCoordinate camera) {
+ CL_Surface surf (pixbuf);
+ surf.draw(-camera.x, -camera.y, g->get_gc());
}
std::vector<std::vector<TerrainType> > Terrain::getTerrain() const {
--- a/src/Terrain.hh Sun Dec 07 19:59:25 2008 +0000
+++ b/src/Terrain.hh Sun Dec 07 20:07:28 2008 +0000
@@ -4,9 +4,14 @@
#include <vector>
#include "Vector.hh"
+#include "GraphicsPointer.hh"
#include "Config.hh"
-enum TerrainType {EMPTY, DIRT, ROCK};
+enum TerrainType {
+ TERRAIN_EMPTY,
+ TERRAIN_DIRT,
+ TERRAIN_ROCK
+};
const Vector DIRECTIONS[] = {
Vector(0,-1),
@@ -19,6 +24,9 @@
Vector(-1,-1)
};
+typedef long int PixelDimension;
+typedef _Vector<PixelDimension> PixelCoordinate;
+
/**
* Terrain class. Represents game terrain and contains member
* functions to manipulate terrain and get info about it.
@@ -30,31 +38,57 @@
* and it uses pixelcoordinates internally.
*/
class Terrain {
- public: // XXX: until we fix Network's access to this
- std::vector<std::vector<TerrainType> > terrain;
-
+public: // XXX: until we fix Network's access to this
+ std::vector<std::vector<TerrainType> > terrain;
+
/**
* Generates pixelbuffer from terrain. Should be used only on
* constructors because this is expected to be slow.
*/
void generatePixelBuffer();
-private:
- // Terrain graphic
+protected:
+ // terrain dimensions
+ PixelDimension map_width, map_height;
+
+ // We can pre-render the terrain as a pixel buffer and then just modify this
CL_PixelBuffer pixbuf;
+
+ // terrain texture
std::vector<std::vector<int> > texture;
- void generate_texture();
-
- void noisifyPixel(CL_Color& col, int x, int y);
+ /**
+ * Default constructor. The width/height are set to zero and the terrain is invalid until it gets updated
+ *
+ * @param scale The "real" width and height of the terrain.
+ */
+ Terrain (void);
/**
- * Get pixel location of a point that is in "real" units.
+ * Constructor.
*
- * @param point Point in "real" units
- * @return Int vector
+ * @param scale The "real" width and height of the terrain.
+ * @param seed Random number generator seed used to create the
+ * terrain.
*/
- Vector getPixelLocation(Vector point) const;
+ Terrain (PixelDimension map_width, PixelDimension map_height, int seed);
+
+ /**
+ * Copy constructor.
+ *
+ * @param t Terrain to be copied.
+ */
+ Terrain (const Terrain &t);
+
+ /**
+ * Destructor
+ */
+ ~Terrain (void) {}
+
+protected:
+ void generate_texture();
+ void noisifyPixel(CL_Color& col, PixelCoordinate pc);
+
/**
* Scale parameter to "pixels"
@@ -62,16 +96,27 @@
* @param x Scaled value
* @return Corresponding value in pixels
*/
- uint16_t scale(float x) const;
+ PixelDimension scale (float x) const;
/**
* Sets to color the correct color of pixel in (x,y)
*/
- void loadPixelColor(CL_Color& color, int x, int y);
+ void loadPixelColor (CL_Color& color, PixelCoordinate pc);
public:
+ /**
+ * Get pixel location of a point that is in "real" units.
+ *
+ * @param point Point in "real" units
+ * @return Int vector
+ */
+ PixelCoordinate getPixelCoordinate (Vector point) const;
- // TODO: This should be private.
+ /**
+ * Return the terrain dimensions à la a PixelCoordinate
+ */
+ PixelCoordinate getDimensions (void) const;
+
/**
* Return the type of terrain at given position. Returns ROCK if
* given point is not inside terrain area.
@@ -80,48 +125,23 @@
* @param y Y coordinate
* @return Terrain type
*/
- TerrainType getType(int32_t x, int32_t y) const;
- //point is just rounded and redirected to that above
- TerrainType getType(Vector point) const;
-
- /**
- * Constructor.
- *
- * @param scale The "real" width and height of the terrain.
- */
- Terrain();
- /**
- * Constructor.
- *
- * @param scale The "real" width and height of the terrain.
- * @param seed Random number generator seed used to create the
- * terrain.
- */
- Terrain(const int &seed);
- /**
- * Copy constructor.
- *
- * @param t Terrain to be copied.
- */
- Terrain(const Terrain &t);
- /**
- * Destructor
- */
- ~Terrain() {}
+ TerrainType getType (PixelDimension px, PixelDimension py) const;
+ TerrainType getType (PixelCoordinate pc) const;
+ TerrainType getType (Vector point) const;
/**
* Check if given point has some terrain.
*
* @param point Point that is in scaled units.
*/
- bool collides(const Vector &point) const;
+ bool collides (const Vector &point) const;
/**
* Check if given line collides with terrain.
*
* @param begin Line begin point in scaled units.
* @param end Line end point in scaled units.
*/
- bool collides(const Vector &begin, const Vector &end) const;
+ bool collides (const Vector &begin, const Vector &end) const;
/**
* Remove a circular area from terrain.
@@ -129,7 +149,7 @@
* @param pos Circle center
* @param r Circle radius
*/
- void removeGround(const Vector &pos, const float &r);
+ void removeGround (const Vector &pos, float r);
/**
* Return normal for the given point.
@@ -137,14 +157,14 @@
* @param point Point for which the normal is calculated.
* @return Normal vector ((0,0) if there's no terrain)
*/
- Vector getNormal(Vector point, Vector prevPoint) const;
+ Vector getNormal (Vector point, Vector prevPoint) const;
/**
* Generate random terrain.
*
* @param seed Seed for the randomnumber generator.
*/
- void generateTerrain(int seed);
+ void generateTerrain (int seed);
/**
* Draw the terrain for given graphicscontext.
@@ -152,7 +172,7 @@
* @param gc CL_GraphicContext
* @param camera - upper left corner of screen
*/
- virtual void draw(CL_GraphicContext *gc, Vector camera = Vector(0, 0));
+ virtual void draw (Graphics *g, PixelCoordinate camera = PixelCoordinate(0, 0));
/**
* Draw part of the terrain for given graphiscontext.
@@ -168,7 +188,8 @@
*
* @param terrain Terrain.
*/
- void setTerrain(const std::vector<std::vector<TerrainType> > &terrain);
+ void setTerrain (const std::vector<std::vector<TerrainType> > &terrain);
+
/**
* Get terrain.
*
@@ -177,6 +198,6 @@
std::vector<std::vector<TerrainType> > getTerrain() const;
};
-Vector direction(const Vector &v);
+Vector direction (const Vector &v);
#endif