Commit ca11300c authored by alistert's avatar alistert

Improvements to player physics.

parent 11f2edb4
......@@ -128,16 +128,16 @@ JJ2LevelPlayer::~JJ2LevelPlayer () {
void JJ2LevelPlayer::reset (unsigned char startX, unsigned char startY) {
event = NULL;
mod = NULL;
energy = 5;
floating = false;
facing = true;
animType = PA_RSTAND;
event = LPE_NONE;
reaction = JJ2PR_NONE;
reactionTime = 0;
jumpHeight = ITOF(92);
jumpY = TTOF(256);
throwY = TTOF(256);
fastFeetTime = 0;
stopTime = 0;
dx = 0;
......@@ -320,15 +320,17 @@ bool JJ2LevelPlayer::touchEvent (JJ2Event* touched, unsigned int ticks, int msps
case 60: // Frozen green spring
jumpY = y - TTOF(14);
event = touched;
throwY = y - TTOF(14);
dx = 0;
event = LPE_SPRING;
break;
case 62: // Spring crate
jumpY = y - TTOF(18);
event = touched;
throwY = y - TTOF(18);
dx = 0;
event = LPE_SPRING;
break;
......@@ -340,22 +342,25 @@ bool JJ2LevelPlayer::touchEvent (JJ2Event* touched, unsigned int ticks, int msps
case 85: // Red spring
jumpY = y - TTOF(7);
event = touched;
throwY = y - TTOF(7);
dx = 0;
event = LPE_SPRING;
break;
case 86: // Green spring
jumpY = y - TTOF(14);
event = touched;
throwY = y - TTOF(14);
dx = 0;
event = LPE_SPRING;
break;
case 87: // Blue spring
jumpY = y - TTOF(18);
event = touched;
throwY = y - TTOF(18);
dx = 0;
event = LPE_SPRING;
break;
......@@ -383,10 +388,10 @@ void JJ2LevelPlayer::send (unsigned char *buffer) {
buffer[30] = (jumpHeight >> 16) & 255;
buffer[31] = (jumpHeight >> 8) & 255;
buffer[32] = jumpHeight & 255;
buffer[33] = jumpY >> 24;
buffer[34] = (jumpY >> 16) & 255;
buffer[35] = (jumpY >> 8) & 255;
buffer[36] = jumpY & 255;
buffer[33] = throwY >> 24;
buffer[34] = (throwY >> 16) & 255;
buffer[35] = (throwY >> 8) & 255;
buffer[36] = throwY & 255;
buffer[37] = x >> 24;
buffer[38] = (x >> 16) & 255;
buffer[39] = (x >> 8) & 255;
......@@ -428,7 +433,7 @@ void JJ2LevelPlayer::receive (unsigned char *buffer) {
floating = buffer[26];
facing = buffer[27];
jumpHeight = (buffer[29] << 24) + (buffer[30] << 16) + (buffer[31] << 8) + buffer[32];
jumpY = (buffer[33] << 24) + (buffer[34] << 16) + (buffer[35] << 8) + buffer[36];
throwY = (buffer[33] << 24) + (buffer[34] << 16) + (buffer[35] << 8) + buffer[36];
x = (buffer[37] << 24) + (buffer[38] << 16) + (buffer[39] << 8) + buffer[40];
y = (buffer[41] << 24) + (buffer[42] << 16) + (buffer[43] << 8) + buffer[44];
......
......@@ -132,6 +132,9 @@
#define PYO_MID (-F10)
// Player speeds
#define PXS_LIMIT ITOF(500)
#define PYS_LIMIT ITOF(500)
#define PXS_WALK ITOF(300)
#define PXS_RUN ITOF(325)
#define PXS_FFRUN ITOF(500)
......@@ -139,11 +142,9 @@
#define PYS_SINK ITOF(150)
#define PYS_JUMP ITOF(-350)
#define PXS_POLE ITOF(3000)
#define PYS_POLE ITOF(1000)
#define PYS_RSPRING ITOF(-500)
#define PYS_GSPRING ITOF(-600)
#define PYS_BSPRING ITOF(-700)
#define PXS_POLE ITOF(3000)
#define PYS_POLE ITOF(3000)
#define PYS_SPRING ITOF(-500)
// Player accelerations
#define PXA_REVERSE 900
......@@ -180,7 +181,6 @@ class JJ2LevelPlayer : public Movable {
private:
bool bird; // Placeholder for eventual JJ2Bird object
JJ2Modifier* mod;
JJ2Event* event;
SDL_Color palette[256];
char anims[PANIMS];
int energy;
......@@ -188,12 +188,13 @@ class JJ2LevelPlayer : public Movable {
int floating; /* 0 = normal, 1 = helicopter ears, 2 = boarding */
bool facing;
unsigned char animType;
PlayerEvent event;
int lookTime; /* Negative if looking up, positive if looking down, 0 if neither */
JJ2PlayerReaction reaction;
unsigned int reactionTime;
unsigned int fireTime;
fixed jumpHeight;
fixed jumpY;
fixed throwX, throwY;
unsigned int fastFeetTime;
unsigned int stopTime;
int gems[4];
......
......@@ -43,12 +43,8 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
JJ2Modifier* nextMod;
bool drop, platform;
unsigned char type;
if (event) type = event->getType();
else type = 0;
nextMod = jj2Level->getModifier(FTOT(x + PXO_MID), FTOT(y + PYO_MID));
......@@ -113,14 +109,11 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
}
if (dx < -PXS_RUN) dx = -PXS_RUN;
if (dx > PXS_RUN) dx = PXS_RUN;
drop = player->pcontrols[C_DOWN];
// Check for platform event, bridge or level mask below player
platform = /*(event >= 3) ||*/
platform = (event == LPE_PLATFORM) ||
jj2Level->checkMaskDown(x + PXO_ML, y + 1, drop) ||
jj2Level->checkMaskDown(x + PXO_MID, y + 1, drop) ||
jj2Level->checkMaskDown(x + PXO_MR, y + 1, drop) ||
......@@ -165,16 +158,12 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
}
if (type) {
if (type == 85) dy = PYS_RSPRING;
else if (type == 86) dy = PYS_GSPRING;
else if (type == 87) dy = PYS_BSPRING;
}
if (dy < -PXS_RUN) dy = -PXS_RUN;
if (dy > PXS_RUN) dy = PXS_RUN;
if (event != LPE_NONE) {
if (event == LPE_SPRING) dy = PYS_SPRING;
else if (event == LPE_FLOAT) dy = PYS_JUMP;
}
} else if (y + PYO_MID > jj2Level->getWaterLevel()) {
......@@ -190,12 +179,12 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
if (!jj2Level->checkMaskUp(x + PXO_MID, y - F36)) {
jumpY = y - jumpHeight;
throwY = y - jumpHeight;
if (dx < 0) jumpY += dx >> 4;
else if (dx > 0) jumpY -= dx >> 4;
if (dx < 0) throwY += dx >> 4;
else if (dx > 0) throwY -= dx >> 4;
event = NULL;
event = LPE_NONE;
}
......@@ -216,9 +205,6 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
}
if (dy < -PXS_RUN) dy = -PXS_RUN;
if (dy > PXS_RUN) dy = PXS_RUN;
} else {
if (platform && player->pcontrols[C_JUMP] &&
......@@ -226,36 +212,30 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
// Jump
jumpY = y - jumpHeight;
throwY = y - jumpHeight;
// Increase jump height if walking/running
if (dx < 0) jumpY += dx >> 3;
else if (dx > 0) jumpY -= dx >> 3;
if (dx < 0) throwY += dx >> 3;
else if (dx > 0) throwY -= dx >> 3;
event = NULL;
event = LPE_NONE;
playSound(S_JUMPA);
}
// Stop jumping
if (!player->pcontrols[C_JUMP] && (type != 85) && (type != 86) && (type != 87))
jumpY = TTOF(256);
if (!player->pcontrols[C_JUMP] && (event != LPE_SPRING) && (event != LPE_FLOAT))
throwY = TTOF(256);
if (y >= jumpY) {
if (y >= throwY) {
// If jumping, rise
dy = (throwY - y - F64) * 4;
dy = (jumpY - y - F64) * 4;
// Spring up speed limit
if ((type == 85) && (dy < PYS_RSPRING)) dy = PYS_RSPRING;
if ((type == 86) && (dy < PYS_GSPRING)) dy = PYS_GSPRING;
if ((type == 87) && (dy < PYS_BSPRING)) dy = PYS_BSPRING;
// Avoid jumping too fast, unless caused by an event
if (!event && (dy < PYS_JUMP)) dy = PYS_JUMP;
// Avoid jumping too fast, unless caused by an event
if ((event == LPE_NONE) && (dy < PYS_JUMP)) dy = PYS_JUMP;
} else if (!platform) {
// Fall under gravity
......@@ -265,7 +245,7 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
}
// Don't descend through platforms
//if ((dy > 0) && (event >= 3)) dy = 0;
if ((dy > 0) && (event == LPE_PLATFORM)) dy = 0;
if (platform && !lookTime) {
......@@ -284,21 +264,21 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
// If there is an obstacle above and the player is not floating up, stop
// rising
if (jj2Level->checkMaskUp(x + PXO_MID, y + PYO_TOP - F4) && (jumpY < y) /*&& (event != 2)*/) {
if (jj2Level->checkMaskUp(x + PXO_MID, y + PYO_TOP - F4) && (throwY < y) && (event != LPE_FLOAT)) {
jumpY = TTOF(256);
throwY = TTOF(256);
if (dy < 0) dy = 0;
/*if ((event != 3) && (event != 4))*/ event = NULL;
if (event != LPE_PLATFORM) event = LPE_NONE;
}
// If jump completed, stop rising
if (y <= jumpY) {
if (y <= throwY) {
jumpY = TTOF(256);
throwY = TTOF(256);
/*if ((event != 3) && (event != 4))*/ event = NULL;
if (event != LPE_PLATFORM) event = LPE_NONE;
}
......@@ -364,7 +344,17 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
} else {
dy = (dy > 0) ? PYS_POLE: -PYS_POLE;
if (dy < 0) {
throwY = y - TTOF(16);
dy = -PYS_POLE;
} else {
dy = PYS_POLE;
}
stopTime = 0;
}
......@@ -422,6 +412,15 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
mod = nextMod;
// Limit speed
if (dx < -PXS_LIMIT) dx = -PXS_LIMIT;
else if (dx > PXS_LIMIT) dx = PXS_LIMIT;
if (dy < -PYS_LIMIT) dy = -PYS_LIMIT;
else if (dy > PYS_LIMIT) dy = PYS_LIMIT;
// Handle firing
if (player->pcontrols[C_FIRE]) {
......@@ -488,7 +487,7 @@ void JJ2LevelPlayer::control (unsigned int ticks, int msps) {
else if (dy < 0) {
if ((type == 85) || (type == 86) || (type == 87)) animType = facing? PA_RSPRING: PA_LSPRING;
if (event == LPE_SPRING) animType = facing? PA_RSPRING: PA_LSPRING;
else animType = facing? PA_RJUMP: PA_LJUMP;
} else if (platform) {
......@@ -541,7 +540,7 @@ void JJ2LevelPlayer::move (unsigned int ticks, int msps) {
int count;
bool drop;
// Apply as much of the trajectory as possible, without going into the
// scenery
......@@ -712,12 +711,12 @@ void JJ2LevelPlayer::move (unsigned int ticks, int msps) {
// If using a float up event and have hit a ceiling, ignore event
/*if ((event == 2) && jj2Level->checkMaskUp(x + PXO_MID, y + PYO_TOP - F4)) {
if ((event == LPE_FLOAT) && jj2Level->checkMaskUp(x + PXO_MID, y + PYO_TOP - F1)) {
jumpY = TTOF(256);
event = 0;
throwY = TTOF(256);
event = LPE_NONE;
}*/
}
if (jj2Level->getStage() == LS_END) return;
......
......@@ -323,7 +323,7 @@ void LevelPlayer::setEvent (unsigned char gridX, unsigned char gridY) {
event = LPE_SPRING;
} else if (set[E_MODIFIER] == 6) event = LPE_PLATFORM;
else if (set[E_BEHAVIOUR] == 28) event = LPE_BRIDGE;
else if (set[E_BEHAVIOUR] == 28) event = LPE_PLATFORM;
else return;
eventX = gridX;
......@@ -371,7 +371,7 @@ bool LevelPlayer::takeEvent (unsigned char gridX, unsigned char gridY, unsigned
case 8: // Boss
case 27: // End of level
if (!getEnergy()) return false;
if (!energy) return false;
if (!gameMode) {
......@@ -389,7 +389,7 @@ bool LevelPlayer::takeEvent (unsigned char gridX, unsigned char gridY, unsigned
case 1: // Invincibility
if (!getEnergy()) return false;
if (!energy) return false;
reaction = PR_INVINCIBLE;
reactionTime = ticks + PRT_INVINCIBLE;
......
......@@ -118,7 +118,6 @@
// Player speeds
#define PXS_WALK ITOF(300)
#define PXS_RUN ITOF(325)
#define PXS_FFRUN ITOF(500)
#define PYS_FALL ITOF(350)
#define PYS_SINK ITOF(150)
#define PYS_JUMP ITOF(-350)
......@@ -128,12 +127,11 @@
#define PXA_STOP 1000
#define PXA_WALK 500
#define PXA_RUN 200
#define PXA_FFRUN 200
#define PYA_GRAVITY 2750
#define PYA_SINK 1000
// Enums
// Enum
enum PlayerReaction {
......@@ -141,12 +139,6 @@ enum PlayerReaction {
};
enum LevelPlayerEvent {
LPE_NONE, LPE_SPRING, LPE_FLOAT, LPE_PLATFORM, LPE_BRIDGE
};
// Classes
......@@ -166,7 +158,7 @@ class LevelPlayer : public Movable {
unsigned char animType;
unsigned char eventX;
unsigned char eventY; /* Position of an event (spring, platform, bridge) */
LevelPlayerEvent event;
PlayerEvent event;
int lookTime; /* Negative if looking up, positive if looking down, 0 if neither */
PlayerReaction reaction;
unsigned int reactionTime;
......
......@@ -98,9 +98,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
if (dx < PXA_STOP * msps) dx = 0;
else dx -= PXA_STOP * msps;
}
if (dx < 0) {
} else if (dx < 0) {
if (dx > -PXA_STOP * msps) dx = 0;
else dx += PXA_STOP * msps;
......@@ -110,11 +108,11 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
}
if (dx < -PXS_RUN) dx = -PXS_RUN;
if (dx > PXS_RUN) dx = PXS_RUN;
else if (dx > PXS_RUN) dx = PXS_RUN;
// Check for platform event, bridge or level mask below player
platform = (event == LPE_PLATFORM) || (event == LPE_BRIDGE) ||
platform = (event == LPE_PLATFORM) ||
level->checkMaskDown(x + PXO_ML, y + 1) ||
level->checkMaskDown(x + PXO_MID, y + 1) ||
level->checkMaskDown(x + PXO_MR, y + 1) ||
......@@ -149,9 +147,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
if (dy < PXA_STOP * msps) dy = 0;
else dy -= PXA_STOP * msps;
}
if (dy < 0) {
} else if (dy < 0) {
if (dy > -PXA_STOP * msps) dy = 0;
else dy += PXA_STOP * msps;
......@@ -168,7 +164,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
}
if (dy < -PXS_RUN) dy = -PXS_RUN;
if (dy > PXS_RUN) dy = PXS_RUN;
else if (dy > PXS_RUN) dy = PXS_RUN;
} else if (y + PYO_MID > level->getWaterLevel()) {
......@@ -211,7 +207,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
}
if (dy < -PXS_RUN) dy = -PXS_RUN;
if (dy > PXS_RUN) dy = PXS_RUN;
else if (dy > PXS_RUN) dy = PXS_RUN;
} else {
......@@ -239,7 +235,6 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
if (y >= jumpY) {
// If jumping, rise
dy = (jumpY - y - F64) * 4;
// Spring/float up speed limit
......@@ -265,7 +260,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
}
// Don't descend through platforms
if ((dy > 0) && ((event == LPE_PLATFORM) || (event == LPE_BRIDGE))) dy = 0;
if ((dy > 0) && (event == LPE_PLATFORM)) dy = 0;
if (platform && !lookTime) {
......@@ -289,7 +284,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
jumpY = TTOF(LH);
if (dy < 0) dy = 0;
if ((event != LPE_PLATFORM) && (event != LPE_BRIDGE)) event = LPE_NONE;
if (event != LPE_PLATFORM) event = LPE_NONE;
}
......@@ -298,7 +293,7 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
jumpY = TTOF(LH);
if ((event != LPE_PLATFORM) && (event != LPE_BRIDGE)) event = LPE_NONE;
if (event != LPE_PLATFORM) event = LPE_NONE;
}
......@@ -384,13 +379,13 @@ void LevelPlayer::control (unsigned int ticks, int msps) {
else animType = facing? PA_RWALK: PA_LWALK;
} else if (!level->checkMaskDown(x + PXO_ML, y + F12) &&
!level->checkMaskDown(x + PXO_L, y + F2) &&
(event != LPE_PLATFORM) && (event != LPE_BRIDGE))
!level->checkMaskDown(x + PXO_L, y + F2) &&
(event != LPE_PLATFORM))
animType = PA_LEDGE;
else if (!level->checkMaskDown(x + PXO_MR, y + F12) &&
!level->checkMaskDown(x + PXO_R, y + F2) &&
(event != LPE_PLATFORM) && (event != LPE_BRIDGE))
!level->checkMaskDown(x + PXO_R, y + F2) &&
(event != LPE_PLATFORM))
animType = PA_REDGE;
else if ((lookTime < 0) && ((int)ticks > 1000 - lookTime))
......
......@@ -49,7 +49,7 @@
#define PCOLOURS 4 /* Number of configurable colour ranges */
// Enum
// Enums
enum PlayerColour {
......@@ -70,6 +70,12 @@ enum PlayerColour {
};
enum PlayerEvent {
LPE_NONE, LPE_SPRING, LPE_FLOAT, LPE_PLATFORM
};
// Classes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment