Platforms correct visualization; opt-in shadow etc
This commit is contained in:
parent
aa0943467f
commit
11d12e3d65
372
sketch.js
372
sketch.js
@ -6,6 +6,7 @@ var fps_recent_values = [];
|
||||
var death_timer;
|
||||
var showDebugData = false;
|
||||
var debug_charTrace = [];
|
||||
var shadows_enabled = false;
|
||||
|
||||
var gameChar;
|
||||
|
||||
@ -26,40 +27,58 @@ function Platform(curGroundIndex, x, width, y) {
|
||||
this.curGroundIndex = curGroundIndex;
|
||||
this.x = x;
|
||||
this.width = width;
|
||||
this.y = y || Math.pow(gameChar.baseJumpingStrength, 2) / 2 - 2 * gameChar.baseJumpingStrength;
|
||||
|
||||
this.draw = function () {
|
||||
push();
|
||||
stroke(0);
|
||||
strokeWeight(2);
|
||||
fill(palette.ground_color0);
|
||||
rect(
|
||||
this.x - this.width,
|
||||
floorPos_y - this.y,
|
||||
width*2, height/100,
|
||||
);
|
||||
// To make platforms jumpable to each other, define a max vertical difference
|
||||
// thru an arithmetic progression dependent on the game character's jumping strength and gravity.
|
||||
this.max_y_deviation =
|
||||
(gameChar.baseJumpingStrength/gravity)*(gameChar.baseJumpingStrength)/2;
|
||||
this.y = y || groundPositions[curGroundIndex] - this.max_y_deviation;
|
||||
|
||||
pop();
|
||||
this.draw = function () {
|
||||
push();
|
||||
stroke(0);
|
||||
strokeWeight(2);
|
||||
fill(palette.ground_colors[curGroundIndex]);
|
||||
rect(
|
||||
this.x - this.width,
|
||||
this.y + height / 100,
|
||||
width * 2,
|
||||
height / 100
|
||||
);
|
||||
pop();
|
||||
};
|
||||
|
||||
this.drawShadow = function () {
|
||||
push();
|
||||
// drawing shadow on the ground
|
||||
noStroke();
|
||||
fill("rgba(0,0,0, 0.15)");
|
||||
rect(
|
||||
this.x - this.width,
|
||||
groundPositions[curGroundIndex],
|
||||
width * 2,
|
||||
height / 100
|
||||
);
|
||||
|
||||
pop();
|
||||
};
|
||||
|
||||
this._isWithinX = function (who) {
|
||||
if (who.x > this.x - this.width && who.x < this.x + this.width) {
|
||||
return true;
|
||||
}
|
||||
if (who.x > this.x - this.width && who.x < this.x + this.width) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.isBelow = function (who) {
|
||||
if (this._isWithinX(who) && who.y > this.y) {
|
||||
return true;
|
||||
}
|
||||
if (this._isWithinX(who) && who.y > this.y) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.isAbove = function (who) {
|
||||
if (this._isWithinX(who) && who.y < this.y) {
|
||||
return true;
|
||||
}
|
||||
if (this._isWithinX(who) && who.y < this.y) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var text_size;
|
||||
// Variables to set colors. Set in setup()
|
||||
@ -71,9 +90,11 @@ function setup() {
|
||||
body_color: color("white"),
|
||||
head_color: color("darkgreen"),
|
||||
sky_color: color("#8E9887"),
|
||||
ground_color0: color("#684622"),
|
||||
ground_color1: color("#734E26"),
|
||||
ground_color2: color("#7F562A"),
|
||||
ground_colors: [
|
||||
color("#874321"),
|
||||
color("#636721"),
|
||||
color("#634345")
|
||||
],
|
||||
river_river_color: color("#56C525"),
|
||||
river_river_wave_color: color("#4BAD21"),
|
||||
river_color: color("#7B672A"),
|
||||
@ -128,7 +149,7 @@ function startGame(level_start) {
|
||||
speed: 5,
|
||||
baseLives: 3,
|
||||
curLives: 3,
|
||||
baseJumpingStrength: 15,
|
||||
baseJumpingStrength: 16,
|
||||
curJumpingStrength: 0,
|
||||
isRight: false,
|
||||
isLeft: false,
|
||||
@ -136,24 +157,25 @@ function startGame(level_start) {
|
||||
isJumping: false,
|
||||
isPlummeting: false,
|
||||
curGroundIndex: 0,
|
||||
|
||||
_updateSprite: function()
|
||||
{
|
||||
if (gameChar.isPlummeting) {
|
||||
gameChar.sprite = 2;
|
||||
} else if (gameChar.isFalling) {
|
||||
gameChar.sprite = 2;
|
||||
if (gameChar.isLeft && !gameChar.isRight) gameChar.sprite = 5;
|
||||
else if (gameChar.isRight && !gameChar.isLeft)
|
||||
gameChar.sprite = 6;
|
||||
} else {
|
||||
if (gameChar.isLeft && !gameChar.isRight) gameChar.sprite = 4;
|
||||
else if (gameChar.isRight && !gameChar.isLeft)
|
||||
gameChar.sprite = 3;
|
||||
else gameChar.sprite = 1;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_updateSprite: function () {
|
||||
if (gameChar.isPlummeting) {
|
||||
gameChar.sprite = 2;
|
||||
} else if (gameChar.isFalling) {
|
||||
gameChar.sprite = 2;
|
||||
if (gameChar.isLeft && !gameChar.isRight)
|
||||
gameChar.sprite = 5;
|
||||
else if (gameChar.isRight && !gameChar.isLeft)
|
||||
gameChar.sprite = 6;
|
||||
} else {
|
||||
if (gameChar.isLeft && !gameChar.isRight)
|
||||
gameChar.sprite = 4;
|
||||
else if (gameChar.isRight && !gameChar.isLeft)
|
||||
gameChar.sprite = 3;
|
||||
else gameChar.sprite = 1;
|
||||
}
|
||||
},
|
||||
|
||||
draw: function () {
|
||||
this._updateSprite();
|
||||
push();
|
||||
@ -325,6 +347,69 @@ function startGame(level_start) {
|
||||
this.y_step /= this.scale;
|
||||
pop();
|
||||
},
|
||||
drawShadow: function () {
|
||||
push();
|
||||
noStroke();
|
||||
this.x_step *= this.scale;
|
||||
this.y_step *= this.scale;
|
||||
fill('rgba(0,0,0,0.2)');
|
||||
if (!gameChar.isPlumetting) shadow_y = groundPositions[gameChar.curGroundIndex];
|
||||
else shadow_y = NaN;
|
||||
ellipse(gameChar.x,
|
||||
shadow_y,
|
||||
gameChar.x_step*5,
|
||||
gameChar.y_step*1.5);
|
||||
this.x_step /= this.scale;
|
||||
this.y_step /= this.scale;
|
||||
pop();
|
||||
},
|
||||
_checkPlayerDie: function () {
|
||||
if (frameCount - death_timer > 60) {
|
||||
if (gameChar.curLives > 1) {
|
||||
gameChar.curLives--;
|
||||
death_timer = undefined;
|
||||
startGame();
|
||||
} else if (gameChar.curLives == 1) {
|
||||
gameChar.curLives--;
|
||||
} else {
|
||||
gameChar.curLives = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
act: function () {
|
||||
if (!gameChar.isPlummeting) {
|
||||
if (gameChar.isLeft && !gameChar.isRight) {
|
||||
gameChar.x -= gameChar.speed;
|
||||
} else if (gameChar.isRight && !gameChar.isLeft) {
|
||||
gameChar.x += gameChar.speed;
|
||||
}
|
||||
|
||||
if (gameChar.isJumping) {
|
||||
gameChar.y -= gameChar.curJumpingStrength;
|
||||
gameChar.curJumpingStrength -= gravity;
|
||||
if (gameChar.curJumpingStrength <= 0) {
|
||||
gameChar.isFalling = true;
|
||||
gameChar.isJumping = false;
|
||||
}
|
||||
} else if (gameChar.isFalling) {
|
||||
gameChar.y -= gameChar.curJumpingStrength;
|
||||
gameChar.curJumpingStrength -= gravity;
|
||||
if (gameChar.y >= gameChar.getCurGroundY()) {
|
||||
gameChar.y = gameChar.getCurGroundY();
|
||||
gameChar.isFalling = false;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
this._checkPlayerDie();
|
||||
// Doing plummeting
|
||||
if (gameChar.isPlummeting) {
|
||||
// using OR operator to set to frameCount in case death_timer is undefined,
|
||||
// but not updating the death_timer again in case it is not undefined.
|
||||
death_timer = death_timer || frameCount;
|
||||
gameChar.y += 3;
|
||||
}
|
||||
},
|
||||
getCurGroundY: function () {
|
||||
return groundPositions[this.curGroundIndex];
|
||||
},
|
||||
@ -348,7 +433,7 @@ function startGame(level_start) {
|
||||
}
|
||||
},
|
||||
};
|
||||
cameraPosX = gameChar.x - width/2;
|
||||
cameraPosX = gameChar.x - width / 2;
|
||||
// Creating trees, clouds, mountains, rivers, collectables.
|
||||
{
|
||||
// Creating trees, clouds, mountains, rivers, collectables, platforms, enemies.
|
||||
@ -446,8 +531,49 @@ function startGame(level_start) {
|
||||
}
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (i == 0) {
|
||||
platforms[0][0] = new Platform(0, 700, 50,
|
||||
pow(gameChar.baseJumpingStrength, 2) / 2 - 2*gameChar.baseJumpingStrength);
|
||||
platforms[0][0] = new Platform(
|
||||
0,
|
||||
700,
|
||||
50,
|
||||
groundPositions[0] - Platform.max_y_deviation
|
||||
);
|
||||
platforms[1][0] = new Platform(
|
||||
1,
|
||||
800,
|
||||
50,
|
||||
groundPositions[1] - Platform.max_y_deviation
|
||||
);
|
||||
platforms[2][0] = new Platform(
|
||||
2,
|
||||
900,
|
||||
50,
|
||||
groundPositions[2] - Platform.max_y_deviation
|
||||
);
|
||||
} else {
|
||||
let groundPosIndex = floor(
|
||||
random(0, groundPositions.length)
|
||||
);
|
||||
// array.slice(-1)[0] gets the last element of an array without removing it,
|
||||
// contrary to array.pop().
|
||||
prev = platforms[groundPosIndex].slice(-1)[0];
|
||||
// stopping generation after the flagpole
|
||||
if (prev.x + prev.width + 155 > finish_position_x) break;
|
||||
platforms[groundPosIndex].push(
|
||||
new Platform(
|
||||
groundPosIndex,
|
||||
prev.x +
|
||||
random(
|
||||
prev.width + 70,
|
||||
prev.width + 155
|
||||
),
|
||||
random(15, 60),
|
||||
max(
|
||||
random(prev.y -
|
||||
prev.max_y_deviation,
|
||||
floorPos_y - prev.max_y_deviation),
|
||||
height / 8)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -470,15 +596,19 @@ function draw() {
|
||||
// -------- GROUND -------------
|
||||
drawGround();
|
||||
|
||||
push();
|
||||
push();
|
||||
fill(0);
|
||||
|
||||
translate(-cameraPosX, 0); // Scrolling everything
|
||||
// Focusing on the character. lerp() ensures fluid camera movement.
|
||||
if (gameChar.x < finish_position_x)
|
||||
cameraPosX = lerp(gameChar.x - width/2, cameraPosX, camera_speed);
|
||||
if (gameChar.x < finish_position_x)
|
||||
cameraPosX = lerp(gameChar.x - width / 2, cameraPosX, camera_speed);
|
||||
else
|
||||
cameraPosX = lerp(finish_position_x - width/2, cameraPosX, camera_speed);
|
||||
cameraPosX = lerp(
|
||||
finish_position_x - width / 2,
|
||||
cameraPosX,
|
||||
camera_speed
|
||||
);
|
||||
|
||||
// -------- CLOUDS --------------
|
||||
drawClouds();
|
||||
@ -492,6 +622,11 @@ function draw() {
|
||||
}
|
||||
// -------- TREES ---------------
|
||||
drawTrees();
|
||||
// -------- PLATFORMS SHADOWS ---
|
||||
if (shadows_enabled)
|
||||
for (i=0; i<groundPositions.length; i++) {
|
||||
drawPlatformsShadows(i);
|
||||
}
|
||||
// -------- COLLECTABLES --------
|
||||
for (i = 0; i < collectables.length; i++) {
|
||||
collectable = collectables[i];
|
||||
@ -501,49 +636,30 @@ function draw() {
|
||||
// -------- FLAGPOLE ------------
|
||||
renderFlagpole();
|
||||
if (!flagpole.isReached) checkFlagpole();
|
||||
// -------- PLATFORMS
|
||||
drawPlatforms();
|
||||
|
||||
// -------- GAME CHARACTER ------
|
||||
{
|
||||
// Behavior
|
||||
if (!gameChar.isPlummeting) {
|
||||
if (gameChar.isLeft && !gameChar.isRight) {
|
||||
gameChar.x -= gameChar.speed;
|
||||
} else if (gameChar.isRight && !gameChar.isLeft) {
|
||||
gameChar.x += gameChar.speed;
|
||||
}
|
||||
|
||||
if (gameChar.isJumping) {
|
||||
gameChar.y -= gameChar.curJumpingStrength;
|
||||
gameChar.curJumpingStrength -= gravity;
|
||||
if (gameChar.curJumpingStrength <= 0) {
|
||||
gameChar.isFalling = true;
|
||||
gameChar.isJumping = false;
|
||||
}
|
||||
} else if (gameChar.isFalling) {
|
||||
gameChar.y -= gameChar.curJumpingStrength;
|
||||
gameChar.curJumpingStrength -= gravity;
|
||||
if (gameChar.y >= gameChar.getCurGroundY()) {
|
||||
gameChar.y = gameChar.getCurGroundY();
|
||||
gameChar.isFalling = false;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
checkPlayerDie();
|
||||
// Doing plummeting
|
||||
if (gameChar.isPlummeting) {
|
||||
if (death_timer == undefined) death_timer = frameCount;
|
||||
gameChar.y += 3;
|
||||
}
|
||||
// Drawing a sprite
|
||||
gameChar.draw();
|
||||
}
|
||||
pop(); // Scrolling
|
||||
// GAMECHAR, PLATFORMS & ENEMIES RENDER
|
||||
complexDraw();
|
||||
// - ------ GAME CHARACTER ------
|
||||
gameChar.act();
|
||||
pop(); // Scrolling end
|
||||
// -------- INTERFACE -----------
|
||||
drawInterface();
|
||||
}
|
||||
function complexDraw() {
|
||||
// Since platforms require being drawn in three different ordrs relative to enemies and the game character,
|
||||
// a function is made to handle this and to decrease clutter.
|
||||
for (i=0; i<=gameChar.curGroundIndex; i++) {
|
||||
drawPlatforms(i);
|
||||
}
|
||||
if (shadows_enabled) gameChar.drawShadow();
|
||||
gameChar.draw();
|
||||
for (i=gameChar.curGroundIndex+1; i<groundPositions.length; i++) {
|
||||
drawPlatforms(i);
|
||||
}
|
||||
}
|
||||
function drawInterface() {
|
||||
push();
|
||||
fill(0);
|
||||
stroke(0);
|
||||
text("Score: " + game_score, 12, text_size);
|
||||
drawLives();
|
||||
if (gameChar.curLives < 1)
|
||||
@ -563,16 +679,16 @@ function draw() {
|
||||
}
|
||||
function drawCharTrace() {
|
||||
debug_charTrace.push([gameChar.x, gameChar.y]);
|
||||
if (debug_charTrace.length>100) debug_charTrace.shift();
|
||||
push()
|
||||
stroke(255,0,0);
|
||||
strokeWeight(3);
|
||||
translate(-cameraPosX, 0);
|
||||
for (i=0;i<debug_charTrace.length;i++) {
|
||||
point(debug_charTrace[i][0], debug_charTrace[i][1]);
|
||||
}
|
||||
translate(cameraPosX, 0);
|
||||
pop();
|
||||
if (debug_charTrace.length > 100) debug_charTrace.shift();
|
||||
push();
|
||||
stroke(255, 0, 0);
|
||||
strokeWeight(3);
|
||||
translate(-cameraPosX, 0);
|
||||
for (i = 0; i < debug_charTrace.length; i++) {
|
||||
point(debug_charTrace[i][0], debug_charTrace[i][1]);
|
||||
}
|
||||
translate(cameraPosX, 0);
|
||||
pop();
|
||||
}
|
||||
function checkRiver(t_river) {
|
||||
if (
|
||||
@ -601,16 +717,16 @@ function checkCollectable(t_collectable) {
|
||||
function drawGround() {
|
||||
push();
|
||||
noStroke();
|
||||
fill(palette.ground_color0);
|
||||
fill(palette.ground_colors[0]);
|
||||
rect(0, floorPos_y, width, height - floorPos_y);
|
||||
fill(palette.ground_color1);
|
||||
fill(palette.ground_colors[1]);
|
||||
rect(
|
||||
0,
|
||||
floorPos_y + (2 * (height - floorPos_y)) / 6,
|
||||
width,
|
||||
floorPos_y + (2 * (height - floorPos_y)) / 6
|
||||
);
|
||||
fill(palette.ground_color2);
|
||||
fill(palette.ground_colors[2]);
|
||||
rect(
|
||||
0,
|
||||
floorPos_y + (4 * (height - floorPos_y)) / 6,
|
||||
@ -843,12 +959,19 @@ function drawTrees() {
|
||||
}
|
||||
}
|
||||
|
||||
function drawPlatforms() {
|
||||
for (i=0; i<groundPositions.length; i++) {
|
||||
for (k=0; k<platforms[i].length;k++) {
|
||||
platforms[i][k].draw();
|
||||
function drawPlatforms(rowIndex) {
|
||||
push();
|
||||
for (k = 0; k < platforms[rowIndex].length; k++) {
|
||||
platforms[rowIndex][k].draw();
|
||||
}
|
||||
}
|
||||
pop();
|
||||
}
|
||||
function drawPlatformsShadows(rowIndex) {
|
||||
push();
|
||||
for (k = 0; k < platforms[rowIndex].length; k++) {
|
||||
platforms[rowIndex][k].drawShadow();
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
function renderFlagpole() {
|
||||
@ -889,19 +1012,7 @@ function checkFlagpole() {
|
||||
flagpole.isReached = true;
|
||||
}
|
||||
}
|
||||
function checkPlayerDie() {
|
||||
if (frameCount - death_timer > 60) {
|
||||
if (gameChar.curLives > 1) {
|
||||
gameChar.curLives--;
|
||||
death_timer = undefined;
|
||||
startGame();
|
||||
} else if (gameChar.curLives == 1) {
|
||||
gameChar.curLives--;
|
||||
} else {
|
||||
gameChar.curLives = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawFps() {
|
||||
push();
|
||||
fps = Math.round(frameRate() * 10) / 10;
|
||||
@ -926,14 +1037,15 @@ function keyPressed() {
|
||||
startGame((level_start = true));
|
||||
}
|
||||
} else if (!gameChar.isPlummeting) {
|
||||
if (keyCode == 65 /*A*/ || keyCode == LEFT_ARROW) gameChar.isLeft = true;
|
||||
if (keyCode == 68 /*D*/ || keyCode == RIGHT_ARROW) gameChar.isRight = true;
|
||||
if (keyCode == 65 /*A*/ || keyCode == LEFT_ARROW)
|
||||
gameChar.isLeft = true;
|
||||
if (keyCode == 68 /*D*/ || keyCode == RIGHT_ARROW)
|
||||
gameChar.isRight = true;
|
||||
if (keyCode == 83 /*S*/ || keyCode == DOWN_ARROW) gameChar.goDown();
|
||||
if (keyCode == 87 /*W*/ || keyCode == UP_ARROW) gameChar.goUp();
|
||||
// Rewrote jumping routine to make it more natural and be able to support platforms and different player dimensions
|
||||
if (
|
||||
(keyCode == 32 /*Space*/ ||
|
||||
keyCode == 88 /*X*/) &&
|
||||
(keyCode == 32 /*Space*/ || keyCode == 88) /*X*/ &&
|
||||
!gameChar.isFalling &&
|
||||
!gameChar.isJumping
|
||||
) {
|
||||
|
Loading…
Reference in New Issue
Block a user