--- a/src/Graphics.cc Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Graphics.cc Sat Dec 06 16:17:05 2008 +0000
@@ -19,7 +19,7 @@
void Graphics::check_input (void) {
LocalPlayer *player;
- PlayerInput_Move input_move = 0;
+ PlayerInput input_mask = 0;
// stop on escape
if (keyboard.get_keycode(CL_KEY_ESCAPE)) {
@@ -32,38 +32,19 @@
if ((player = state.getLocalPlayer()) == NULL)
return;
- // handle movement
- if (keyboard.get_keycode(CL_KEY_LEFT))
- input_move |= INPUT_MOVE_LEFT;
-
- if (keyboard.get_keycode(CL_KEY_RIGHT))
- input_move |= INPUT_MOVE_RIGHT;
-
- if (keyboard.get_keycode(CL_KEY_UP))
- input_move |= INPUT_MOVE_UP;
-
- if (keyboard.get_keycode(CL_KEY_DOWN))
- input_move |= INPUT_MOVE_DOWN;
-
- if (keyboard.get_keycode(CL_KEY_RSHIFT))
- input_move |= INPUT_MOVE_JUMP;
-
+ // dump debug info on stderr
if (keyboard.get_keycode(CL_KEY_I))
- player->debugInfo();
+ player->printDebugInfo();
- if (keyboard.get_keycode(CL_KEY_F)) {
- input_move |= INPUT_SHOOT;
+ // check our keymap
+ for (InputKeymapEntry *e = getGlobalInputKeymap(); e->keycode && e->input; e++) {
+ if (keyboard.get_keycode(e->keycode))
+ input_mask |= e->input;
}
-
- if (keyboard.get_keycode(CL_KEY_D))
- input_move |= INPUT_CHANGE;
-
- if (keyboard.get_keycode(CL_KEY_M))
- input_move |= INPUT_MOVE_DIG;
-
- // apply movement if applicable
- if (input_move)
- player->handleMove(input_move);
+
+ // apply input if applicable
+ if (input_mask)
+ player->handleInput(input_mask);
}
void Graphics::do_redraw (void) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Input.cc Sat Dec 06 16:17:05 2008 +0000
@@ -0,0 +1,20 @@
+
+#define INPUT_CC
+
+#include "Input.hh"
+
+static InputKeymapEntry INPUT_KEYMAP[] = {
+ { CL_KEY_UP, INPUT_AIM_UP },
+ { CL_KEY_DOWN, INPUT_AIM_DOWN },
+ { CL_KEY_LEFT, INPUT_MOVE_LEFT },
+ { CL_KEY_RIGHT, INPUT_MOVE_RIGHT },
+ { CL_KEY_RSHIFT, INPUT_JUMP },
+ { CL_KEY_M, INPUT_DIG },
+ { CL_KEY_F, INPUT_SHOOT },
+ { CL_KEY_D, INPUT_CHANGE },
+ { 0, (_PlayerInput) 0 }
+};
+
+InputKeymapEntry* getGlobalInputKeymap (void) {
+ return INPUT_KEYMAP;
+}
--- a/src/Input.hh Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Input.hh Sat Dec 06 16:17:05 2008 +0000
@@ -1,22 +1,34 @@
#ifndef INPUT_HH
#define INPUT_HH
-const uint16_t INPUT_INTERVAL_MS = 20;
+#include <stdint.h>
+#include <ClanLib/Display/keys.h>
-enum {
- // XXX: aiming is not movement?
- INPUT_MOVE_UP = 0x0001,
- INPUT_MOVE_DOWN = 0x0002,
+// const uint16_t INPUT_INTERVAL_MS = 20;
+
+enum _PlayerInput {
+ INPUT_AIM_UP = 0x0001,
+ INPUT_AIM_DOWN = 0x0002,
INPUT_MOVE_LEFT = 0x0004,
INPUT_MOVE_RIGHT = 0x0008,
- INPUT_MOVE_JUMP = 0x0010,
- INPUT_MOVE_DIG = 0x0020,
+ INPUT_JUMP = 0x0010,
+ INPUT_DIG = 0x0020,
INPUT_SHOOT = 0x0040,
INPUT_CHANGE = 0x0080,
};
-typedef uint16_t PlayerInput_Move;
+typedef uint16_t PlayerInput;
+
+struct InputKeymapEntry {
+ int keycode;
+ enum _PlayerInput input;
+};
+
+/*
+ * Get the global input keymap
+ */
+InputKeymapEntry* getGlobalInputKeymap (void);
#endif
--- a/src/Network/Client.cc Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Network/Client.cc Sat Dec 06 16:17:05 2008 +0000
@@ -145,7 +145,7 @@
}
-void NetworkClientLocalPlayer::handleMove (PlayerInput_Move input) {
+void NetworkClientLocalPlayer::handleInput (PlayerInput input) {
// always send move, in all cases
NetworkPacket pkt;
pkt.write_uint16(input);
--- a/src/Network/Client.hh Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Network/Client.hh Sat Dec 06 16:17:05 2008 +0000
@@ -59,7 +59,7 @@
public:
NetworkClientLocalPlayer (NetworkClient &client, NetworkObject_Client *obj, Vector position);
- virtual void handleMove (PlayerInput_Move input);
+ virtual void handleInput (PlayerInput input);
};
class NetworkClientRemotePlayer : public NetworkClientPlayerHelper, public RemotePlayer {
--- a/src/Network/Server.cc Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Network/Server.cc Sat Dec 06 16:17:05 2008 +0000
@@ -111,12 +111,12 @@
return;
}
- PlayerInput_Move input = pkt.read_uint16();
+ PlayerInput input = pkt.read_uint16();
Engine::log(INFO, "server_player.on_move") << "player=" << obj << ", old_pos=" << position << ", input=" << input;
// apply input
- handleMove(input);
+ handleInput(input);
// send position update
send_position_update();
--- a/src/PhysicsObject.cc Sat Dec 06 14:36:37 2008 +0000
+++ b/src/PhysicsObject.cc Sat Dec 06 16:17:05 2008 +0000
@@ -7,7 +7,7 @@
PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass,
Vector position, Vector velocity)
: world(world), position(position), velocity(velocity),
- mass(mass), inAir(true), aim(0), facingRight(true), reloadTimer(0) {
+ mass(mass), inAir(true), aim(0), facingRight(true) {
// TODO: Is thir the right way to do this?
//world.addPlayerObject(this);
}
@@ -64,7 +64,7 @@
float velocity = PLAYER_WALK_SPEED;
float walkAmount = (velocity*dt)/1000;
Vector reached = this->position;
- while(walkAmount > 0 && !this->inAir) {
+ while (walkAmount > 0 && !this->inAir) {
this->position = walk_one_step((1 < walkAmount ? 1 : walkAmount), right);
walkAmount--;
}
@@ -112,12 +112,6 @@
* integration and collision detection.
*/
void PhysicsObject::updatePosition (TimeMS dt) {
-
- // Reloads weapon if not reloaded
- reloadTimer -= dt;
- if(reloadTimer < 0)
- reloadTimer = 0;
-
// Add gravity to the force queue
forceq.push(world.gravity);
@@ -330,10 +324,6 @@
this->updatePosition(tick_length);
}
-bool PhysicsObject::canShoot() {
- return this->reloadTimer <= 0;
-}
-
void PhysicsObject::draw(CL_GraphicContext *gc) {
CL_Quad player(
(position+shape[0]).x, (position+shape[0]).y,
--- a/src/PhysicsObject.hh Sat Dec 06 14:36:37 2008 +0000
+++ b/src/PhysicsObject.hh Sat Dec 06 16:17:05 2008 +0000
@@ -34,9 +34,6 @@
float aim; // Aim direction (half circle)
bool facingRight; // Player facing
- //
- int reloadTimer;
-
PhysicsObject(PhysicsWorld &world, float mass, Vector position,
Vector velocity);
~PhysicsObject() {}
@@ -192,13 +189,7 @@
/**
* Update object in physics simulation.
*/
- void tick(TimeMS tick_length);
-
- /**
- * @return whether this PhysicsObject can shoot or not
- * This is in PhysicsObject for larpa-like shots
- */
- bool canShoot();
+ virtual void tick (TimeMS tick_length);
/**
* Draw object
--- a/src/Player.cc Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Player.cc Sat Dec 06 16:17:05 2008 +0000
@@ -22,7 +22,7 @@
// TODO: arsenal's size should be affected by some value
// and weapons should be loaded from somewhere, not generated here
for (int i = 0; i < 5; i++) {
- arsenal.push_back(Weapon(10000, (5-i)*40+30, i*6+5, i*100+50, "asdf"));
+ arsenal.push_back(Weapon(state, 10000, (5 - i) * 40 + 30, i * 6 + 5, i * 100 + 50, "asdf"));
}
// build the player's shape
@@ -52,100 +52,119 @@
}
-void Player::debugInfo (void) {
- Engine::log(DEBUG, "Player.debugInfo") << "In air: " << this->inAir;
-}
+void Player::handleShoot (Weapon &weapon) {
+ Vector unitVectorAim = (facingRight ?
+ Vector(std::cos(aim), -std::sin(aim)) :
+ Vector(-std::cos(aim), -std::sin(aim))
+ );
+
+ // XXX: what does the PHYSICS_TICK_MS stuff mean?
+ float shotspeed = weapon.getVelocity() * PHYSICS_TICK_MS / 2;
-/**
- * shoots the selected weapon.
- * TODO: selection and weapon information
- */
-void LocalPlayer::shoot (void) {
- // here should be somehow considered which projectile it is
- if(!canShoot())
- return;
- reloadTimer += getWeapon().reloadTime;
- Vector unitVectorAim = facingRight ? Vector(std::cos(aim), -std::sin(aim)) :
- Vector(-std::cos(aim), -std::sin(aim));
- float shotspeed = getWeapon().velocity*PHYSICS_TICK_MS/2;
Vector shotRelativeVelocity = unitVectorAim * shotspeed;
Vector shotVelocity = this->velocity + shotRelativeVelocity;
- Vector shotPosition = this->position + unitVectorAim*10;
- new Projectile(this->state, shotPosition, shotVelocity, true, getWeapon().explosionRadius);
+ Vector shotPosition = this->position + unitVectorAim * 10;
+
+ weapon.shoot(shotPosition, shotVelocity);
}
-void LocalPlayer::handleMove (PlayerInput_Move input) {
- float fx = 0; // Force in x-direction
- float da = 0; // Crosshair angle
-
- // handle left/right
- if ((input & INPUT_MOVE_LEFT) && (velocity.x > -PLAYER_MAX_SPEED))
- fx -= PLAYER_MOVE_FORCE;
-
- if ((input & INPUT_MOVE_RIGHT) && (velocity.x < PLAYER_MAX_SPEED))
- fx += PLAYER_MOVE_FORCE;
+void Player::printDebugInfo (void) {
+ Engine::log(DEBUG, "layer.debug") << "In air: " << this->inAir;
+}
+
+void Player::tick (TimeMS dt) {
+ // let PhysicsObject execute
+ PhysicsObject::tick(dt);
+
+ // tick current weapon reload
+ getWeapon().tickReload(dt);
+}
- if (input & INPUT_MOVE_UP)
- da += CROSSHAIR_ANGLE_SPEED;
+void LocalPlayer::handleInput (PlayerInput input) {
+ // Movement force, vertical is always zero
+ Vector move_force = Vector(0, 0);
- if (input & INPUT_MOVE_DOWN)
- da -= CROSSHAIR_ANGLE_SPEED;
+ // Crosshair angle change
+ float aim_delta = 0;
- if (input & INPUT_MOVE_JUMP) {
- if ((input & INPUT_MOVE_LEFT))
+ // handle movement left/right by applying a horizontal force, but limit the player's speed
+ if ((input & INPUT_MOVE_LEFT) && (velocity.x > -PLAYER_MAX_SPEED)) {
+ setFacing(false);
+ move_force.x -= PLAYER_MOVE_FORCE;
+
+ }
+
+ if ((input & INPUT_MOVE_RIGHT) && (velocity.x < PLAYER_MAX_SPEED)) {
+ setFacing(true);
+ move_force.x += PLAYER_MOVE_FORCE;
+ }
+
+ // handle aim by creating a aim angle delta
+ if (input & INPUT_AIM_UP)
+ aim_delta += CROSSHAIR_ANGLE_SPEED;
+
+ if (input & INPUT_AIM_DOWN)
+ aim_delta -= CROSSHAIR_ANGLE_SPEED;
+
+ // handle jumping by invoking the jump method
+ // XXX: the direction should ideally be given using some other method
+ if (input & INPUT_JUMP) {
+ if (input & INPUT_MOVE_LEFT)
jump(-1);
- else if ((input & INPUT_MOVE_RIGHT))
+
+ else if (input & INPUT_MOVE_RIGHT)
jump(1);
+
else
jump(0);
}
+
+ // outsource digging to Player::handleDig, since this modifies the Terrain and Network needs to know
+ if (input & INPUT_DIG) {
+ handleDig(position, 15);
- if (input & INPUT_MOVE_DIG) {
// Should create Projectile which destroys ground, but also should be destroyed then,
// but it doesn't.
// But this now just segfaults
// world.addObject(new Projectile(state, position, true));
-
- handleDig(position, 15);
}
-
+
+ // XXX: currently not network safe
if (input & INPUT_CHANGE) {
- if(changing) {
+ if (changing) {
} else {
changing = true;
- selectedWeapon = (selectedWeapon+1)%arsenal.size();
+ selectedWeapon = (selectedWeapon + 1) % arsenal.size();
Engine::log(DEBUG, "Player.cc:input ") << "changed weapon " << selectedWeapon;
}
} else {
changing = false;
}
-
- if (input & INPUT_SHOOT) {
- this->shoot();
+
+ // validate shoot events, and then outsource to handleShoot so Network can intercept it
+ if (input & INPUT_SHOOT && getWeapon().canShoot()) {
+ this->handleShoot(getWeapon());
}
-
-
+
+ // XXX: how should this be written?
+ if (move_force.x != 0)
+ animation_step = (animation_step + 1) % img_num_step;
- // Player facing
- if (fx < 0) setFacing(false);
- else if (fx > 0) setFacing(true);
-
- if (fx != 0) animation_step = (animation_step+1)%img_num_step;
+ // apply aim delta
+ if (aim_delta)
+ changeAim(aim_delta);
-
- this->changeAim(da); // Move crosshair
-
- // Apply force
- applyForce(Vector(fx, 0));
-
+ // apply force
+ if (!move_force.zero())
+ applyForce(move_force);
}
Weapon& Player::getWeapon() {
- return arsenal[selectedWeapon%arsenal.size()];
+ return arsenal[selectedWeapon % arsenal.size()];
}
-void Player::draw(CL_GraphicContext *gc) {
+void Player::draw (CL_GraphicContext *gc) {
int aim_img_idx = (int)((1 - (getAim()+KG_PI/2)/KG_PI)*img_num_aim);
int step_img_idx = animation_step%img_num_step;
@@ -154,7 +173,8 @@
skin_surface = CL_Surface(PLAYER_SKIN_PATH);
skin_loaded = true;
}
-
+
+ // XXX: this logic looks weird
CL_Rectf destination(position.x - 4, position.y - 4, position.x + 5, position.y + 4);
if (!getFacing()) {
@@ -162,9 +182,14 @@
}
skin_surface.draw_subpixel(
- CL_Rectf(1+step_img_idx*img_width, aim_img_idx*img_height+1, 1+(1+step_img_idx)*img_width, (aim_img_idx+1)*img_height+1),
- destination,
- gc);
+ CL_Rectf(
+ 1 + step_img_idx * img_width,
+ aim_img_idx * img_height + 1,
+ 1 + (1 + step_img_idx) * img_width,
+ (aim_img_idx + 1) * img_height + 1
+ ),
+ destination, gc
+ );
const uint16_t chlen = 10;
uint16_t x = position.x;
--- a/src/Player.hh Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Player.hh Sat Dec 06 16:17:05 2008 +0000
@@ -25,12 +25,25 @@
Player (void);
Player (GameState &state, Vector position, bool visible);
+ // used by the network code to execute actions for players
virtual void handleDig (Vector position, float radius);
-
+ virtual void handleShoot (Weapon &weapon);
+
+ /*
+ *
+ */
Weapon& getWeapon();
public:
- void debugInfo ();
+ /*
+ * Prints random things via Engine::log
+ */
+ void printDebugInfo ();
+
+ /*
+ * Overrides PhysicsObject::tick to also advance game state
+ */
+ virtual void tick (TimeMS dt);
/*
* Drawing requires the skin texture, which is loaded on-demand when draw is called
@@ -42,8 +55,12 @@
class LocalPlayer : public virtual Player {
public:
- virtual void handleMove (PlayerInput_Move input);
- void shoot (void);
+ /*
+ * Called to invoke some action on this player that we control, either by Graphics or NetworkServer.
+ *
+ * NetworkClientLocalPlayer overrides this to send the input to the server, which then handles it
+ */
+ virtual void handleInput (PlayerInput input);
};
class RemotePlayer : public virtual Player {
--- a/src/Vector.hh Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Vector.hh Sat Dec 06 16:17:05 2008 +0000
@@ -76,6 +76,12 @@
_Vector roundToInt() const {
return _Vector((int)(x), (int)(y));
}
+
+ // test Vectors as booleans
+ // XXX: comparing floats against zero... is a bad idea?
+ bool zero(void) const {
+ return x == 0 && y == 0;
+ }
};
// Unary operators
--- a/src/Weapon.cc Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Weapon.cc Sat Dec 06 16:17:05 2008 +0000
@@ -1,9 +1,40 @@
#include "Weapon.hh"
-Weapon::Weapon(TickCount age, float velocity, float explosionRadius, int reloadTime, std::string name)
- : age(age), velocity(velocity), explosionRadius(explosionRadius), reloadTime(reloadTime), name(name) {
+Weapon::Weapon(GameState &st, TickCount age, float velocity, float explosionRadius, int reloadTime, std::string name) :
+ st(st), age(age), velocity(velocity), explosionRadius(explosionRadius), reloadTime(reloadTime), name(name), reloadTimer(0)
+{
+
}
-Weapon::Weapon(const Weapon& orig)
- : age(orig.age), velocity(orig.velocity), explosionRadius(orig.explosionRadius), reloadTime(orig.reloadTime), name(orig.name) {
+Weapon::Weapon(const Weapon& orig) :
+ st(orig.st), age(orig.age), velocity(orig.velocity), explosionRadius(orig.explosionRadius), reloadTime(orig.reloadTime), name(orig.name)
+{
+
}
+
+Weapon& Weapon::operator= (const Weapon& orig) {
+ st = orig.st;
+ age = orig.age;
+ velocity = orig.velocity;
+ explosionRadius = orig.explosionRadius;
+ reloadTime = orig.reloadTime;
+ name = orig.name;
+}
+
+void Weapon::tickReload (TimeMS dt) {
+ reloadTimer -= dt;
+ if (reloadTimer < 0)
+ reloadTimer = 0;
+}
+
+bool Weapon::canShoot() {
+ return (reloadTimer == 0);
+}
+
+Projectile* Weapon::shoot (Vector position, Vector velocity) {
+ // set the reload timer
+ reloadTimer = reloadTime;
+
+ return new Projectile(st, position, velocity, true, explosionRadius);
+}
+
--- a/src/Weapon.hh Sat Dec 06 14:36:37 2008 +0000
+++ b/src/Weapon.hh Sat Dec 06 16:17:05 2008 +0000
@@ -1,35 +1,45 @@
#ifndef WEAPON_HH
#define WEAPON_HH
+// forward-declare
+class Weapon;
+
+#include "GameState.hh"
#include "Timer.hh"
#include <string>
class Weapon {
-public:
-/* const TickCount age;
- const float velocity;
- const float explosionRadius;
- const int reloadTime; //in ms
-
- const int clipSize;
- const bool visible;
-
- const std::string name;
-*/
-
- TickCount age;
+protected:
+ GameState &st;
+ std::string name;
float velocity;
float explosionRadius;
int reloadTime; //in ms
int clipSize;
- bool visible;
- std::string name;
+ bool visible;
+ TickCount age;
+ int reloadTimer;
- Weapon(TickCount age, float velocity, float explosionRadius, int reloadTime, std::string name);
+public:
+ Weapon (GameState &st, TickCount age, float velocity, float explosionRadius, int reloadTime, std::string name);
+ Weapon (const Weapon& orig);
+ Weapon& operator= (const Weapon& orig);
+
+ // advance the reload timer
+ void tickReload (TimeMS dt);
+
+ // can the weapon be fired (not reloading, have a clip, etc)
+ bool canShoot (void);
+
+ // get the weapon projectile velocity
+ float getVelocity (void) { return velocity; }
- Weapon(const Weapon& orig);
+ /*
+ * Fire the Weapon! Position and velocity are the initial position and velocity for the resulting projectile
+ */
+ Projectile* shoot (Vector position, Vector velocity);
};
#endif