/**** * Classes ****/ /** * config { * x : Number || 0, * y : Number || 0, * rotation : Number || 0, * } **/ var ConfigContainer = Container.expand(function (config) { var self = Container.call(this); config = config || {}; ; self.x = config.x || 0; self.y = config.y || 0; self.rotation = config.rotation || 0; if (config.scale !== undefined || config.scaleX !== undefined || config.scaleY !== undefined) { var scaleX = config.scaleX !== undefined ? config.scaleX : config.scale !== undefined ? config.scale : 1; var scaleY = config.scaleY !== undefined ? config.scaleY : config.scale !== undefined ? config.scale : 1; self.scale.set(scaleX, scaleY); } ; return self; }); var Sun = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); for (var i = 0; i < 10; i++) { self.attachAsset('circle', { width: 500 + 200 * i, height: 500 + 200 * i, color: 0xFFFF00, alpha: 0.1, anchorX: 0.5, anchorY: 0.5 }); } var sunAsset = self.attachAsset('sun', { anchorX: 0.5075, anchorY: 0.5, alpha: 0.75 }); ; self.update = update; ; function update() { if (LK.ticks % 30 == 0) { //sunAsset.scale.x *= -1; //TODO Other animation } } }); var RoadSegment = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var background = self.addChild(new Container()); self.attachAsset('roadSegment', { anchorX: 1, anchorY: 1 }); self.attachAsset('roadSegment', { anchorX: 1, anchorY: 1, scaleX: 0.95, scaleY: 0.95, tint: 0x555555 }); if (config.index % 3 === 0) { attachAssetRadial(self, 'square', { offset: 200, width: 100, height: 10, anchorR: 0.5, anchorX: 0.5, anchorY: 0.5 }); } ; self.update = update; self.regenerate = regenerate; self.fadeout = false; self.distance = config.distance; self.step = config.step; self.stepChance = config.stepChance; self.previous = config.previous; ; function attachAssetRadial(parent, asset, obj) { var offsetTotal = ROAD_SEGMENT_HEIGHT - (obj.offset || 10); var rotation = -(1 - obj.anchorR) * ROAD_SEGMENT_ANGLE; parent.attachAsset(asset, { x: Math.sin(rotation) * offsetTotal, y: Math.cos(rotation) * -offsetTotal, width: obj.width, height: obj.height, anchorX: obj.anchorX, anchorY: obj.anchorY, scaleX: obj.scaleX || 1, scaleY: obj.scaleY || 1, rotation: (obj.rotation || 0) + rotation }); } function generateBackground() { console.log(self.distance); background.removeChildren(); var plantCount = Math.floor(Math.random() * (ROAD_GEN_PLANT_MAX + 1)); if (self.distance === SCORE_TOTAL_DISTANCE) { attachAssetRadial(background, 'flag', { anchorR: 0.5, anchorX: 0.1, anchorY: 1 }); } else { if (Math.random() < ROAD_GEN_TREE_CHANCE) { var treeIndex = Math.floor(Math.random() * ROAD_GEN_TREE_ASSETS); var scale = 0.9 + 0.2 * Math.random(); attachAssetRadial(background, 'tree' + treeIndex, { anchorR: 0.4 + 0.2 * Math.random(), anchorX: 0.5, anchorY: 1, scaleX: scale, scaleY: scale }); } for (var i = 0; i < plantCount; i++) { var plantIndex = Math.floor(Math.random() * ROAD_GEN_PLANT_ASSETS); var scale = 0.9 + 0.2 * Math.random(); attachAssetRadial(background, 'plant' + plantIndex, { anchorR: 0.1 + 0.8 * Math.random(), anchorX: 0.5, anchorY: 1, scaleX: Math.random() < 0.5 ? -scale : scale, scaleY: scale }); } } if (Math.random() < ROAD_GEN_CLOUD_CHANCE) { var cloudIndex = Math.floor(Math.random() * ROAD_GEN_CLOUD_ASSETS); var scale = 1.0 + 1.5 * Math.random(); attachAssetRadial(background, 'cloud' + cloudIndex, { offset: -800, anchorR: -1.0 + 2.0 * Math.random(), anchorX: 0.5, anchorY: 0.5, scaleX: scale, scaleY: scale }); } } function regenerate(incrementDistance) { if (incrementDistance) { self.distance += SCORE_SEGMENT_DISTANCE * ROAD_SEGMENT_COUNT; } var stepping = self.distance <= SCORE_TOTAL_DISTANCE; var stepChance = self.previous.stepChance; var stepUp = stepping && (self.previous.step < ROAD_STEP_COUNT ? Math.random() < self.stepChance : false); var stepDown = stepping && (self.previous.step > 0 ? Math.random() < self.stepChance : false); if (stepUp || stepDown) { if (stepUp && stepDown) { if (Math.random() < 0.5) { stepDown = false; } else { stepUp = false; } } self.step = self.previous.step + (stepUp ? 1 : -1); self.stepChance = ROAD_STEP_CHANCE_BASE; } else { self.step = self.previous.step; self.stepChance = self.previous.stepChance + ROAD_STEP_CHANCE_INCREMENT; } generateBackground(); self.fadeout = false; rescale(); } function update() { if (self.fadeout && self.alpha > 0) { if ((self.alpha -= ROAD_SEGMENT_FADEOUT) < 0) { self.alpha = 0; } } else if (!self.fadeout && self.alpha < 1) { if ((self.alpha += ROAD_SEGMENT_FADEOUT) > 1) { self.alpha = 1; } } } function rescale() { var newScale = (ROAD_STEP_HEIGHT_BASE + self.step * ROAD_STEP_HEIGHT_INCREMENT) / ROAD_SEGMENT_HEIGHT; // TEMP self.scale.set(newScale); } ; rescale(); }); var Road = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var segments = []; for (var i = 0; i < ROAD_SEGMENT_COUNT; i++) { var segment = segments[i] = self.addChild(new RoadSegment({ index: i, previous: i > 0 ? segments[i - 1] : undefined, rotation: i * ROAD_SEGMENT_ANGLE, distance: (i - 1) * SCORE_SEGMENT_DISTANCE, stepChance: ROAD_STEP_CHANCE_BASE, step: ROAD_STEP_DEFAULT })); if (i === ROAD_SEGMENT_COUNT - 1) { segments[0].previous = segment; } if (i >= ROAD_FREE_RUN_COUNT) { segment.regenerate(); } self.attachAsset('roadSegment', { anchorX: 1, anchorY: 1, scaleX: 0.27, scaleY: 0.27, rotation: i * ROAD_SEGMENT_ANGLE }); } self.attachAsset('circle', { width: 500, height: 500, anchorX: 0.5, anchorY: 0.5, tint: 0x222222 }); self.attachAsset('circle', { width: 490, height: 490, anchorX: 0.5, anchorY: 0.5, tint: 0x87CEEB }); var destroyIndex = -1; var regenerateIndex = -1; ; self.rotate = rotate; self.getIndex = getIndex; self.getNode = getNode; self.getNodeDist = getNodeDist; ; function rotate(speed) { self.rotation -= speed; var newDestroyIndex = getIndex(ROAD_SEGMENT_DESTROY); var newRegenerateIndex = getIndex(20); // TEMP if (newDestroyIndex >= 0 && newDestroyIndex !== destroyIndex && !segments[newDestroyIndex].fadeout) { destroyIndex = newDestroyIndex; segments[destroyIndex].fadeout = true; } if (newRegenerateIndex >= 0 && newRegenerateIndex !== regenerateIndex && segments[newRegenerateIndex].fadeout) { regenerateIndex = newRegenerateIndex; segments[regenerateIndex].regenerate(true); } } function getIndex(shift) { return Math.floor(-self.rotation / MATH_2_PI * ROAD_SEGMENT_COUNT + (shift || 0) + 1) % ROAD_SEGMENT_COUNT; } function getNode(shift) { return segments[getIndex(shift)]; } function getNodeDist() { return ROAD_SEGMENT_ANGLE - -self.rotation % ROAD_SEGMENT_ANGLE; } }); var PlayerBody = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); // Animation settings var animation = animationStand; var alpha = 0; var blendAnimation = undefined; var blendDecrement = 0; var blendAlpha = 0; var afterTint = 0xAAAAAA; // Body settings var bodyOffsetY = config.y || 0; var pelvisOffsetX = -10; var armUpperAngle = -3 * MATH_EIGHTH_PI; var armUpperOffsetX = 15; var armUpperOffsetY = 30; var armLowerAngle = -MATH_QUARTER_PI; var armLowerOffsetY = 90; var legUpperAngle = 3 * MATH_EIGHTH_PI; var legUpperOffsetX = 10; var legLowerOffsetY = 135; var footOffsetY = 100; // Create and attach body parts var armUpperRight = self.addChild(new ConfigContainer({ y: armUpperOffsetY })); var legUpperRight = self.addChild(new ConfigContainer({ x: pelvisOffsetX + legUpperOffsetX })); var torso = self.attachAsset('torso', { anchorX: 0.5 }); var head = self.attachAsset('head', { anchorX: 0.15, anchorY: 0.95 }); var pelvis = self.attachAsset('pelvis', { x: pelvisOffsetX, y: torso.height, anchorX: 0.5, anchorY: 0.2, tint: afterTint }); var legUpperLeft = self.addChild(new ConfigContainer({ x: pelvisOffsetX - legUpperOffsetX })); var armUpperLeft = self.addChild(new ConfigContainer({ y: armUpperOffsetY })); // Arm extensions armUpperRight.attachAsset('upperArm', { rotation: armUpperAngle, anchorX: 0.85, anchorY: 0.25, tint: afterTint }); armUpperLeft.attachAsset('upperArm', { rotation: armUpperAngle, anchorX: 0.85, anchorY: 0.25 }); var armLowerRight = armUpperRight.attachAsset('lowerArm', { y: armLowerOffsetY, rotation: armLowerAngle, anchorX: 0.95, anchorY: 0.05, tint: afterTint }); var armLowerLeft = armUpperLeft.attachAsset('lowerArm', { y: armLowerOffsetY, rotation: armLowerAngle, anchorX: 0.95, anchorY: 0.05 }); // Leg extensions legUpperRight.attachAsset('upperLeg', { rotation: legUpperAngle, anchorY: 0.1, tint: afterTint }); legUpperLeft.attachAsset('upperLeg', { rotation: legUpperAngle, anchorY: 0.1 }); var legLowerRight = legUpperRight.attachAsset('lowerLeg', { y: legLowerOffsetY, anchorX: 0.65, tint: afterTint }); var legLowerLeft = legUpperLeft.attachAsset('lowerLeg', { y: legLowerOffsetY, anchorX: 0.65 }); var footRight = legLowerRight.attachAsset('foot', { y: footOffsetY, anchorX: 0.2, anchorY: 0.05, tint: afterTint }); var footLeft = legLowerLeft.attachAsset('foot', { y: footOffsetY, anchorX: 0.2, anchorY: 0.05 }); // Additional positioning armUpperLeft.x = -torso.width / 2 + armUpperOffsetX; armUpperRight.x = torso.width / 2 - armUpperOffsetX; legUpperLeft.y = torso.height + pelvis.height / 3; legUpperRight.y = torso.height + pelvis.height / 3; ; self.animate = animate; self.pushAnimation = pushAnimation; ; function animate(increment) { alpha = (alpha + increment) % 1; if (blendAlpha > 0) { if ((blendAlpha -= blendDecrement) <= 0) { blendAlpha = 0; blendAnimation = undefined; } } var pose = animation(alpha); var blendPose = blendAnimation && blendAnimation(alpha); self.y = animateProperty(pose, blendPose, blendAlpha, 'BODY_OFFSET', bodyOffsetY); head.rotation = animateProperty(pose, blendPose, blendAlpha, 'HEAD_ROTATION'); armUpperRight.rotation = animateProperty(pose, blendPose, blendAlpha, 'ARM_UPPER_RIGHT_ROTATION'); armUpperLeft.rotation = animateProperty(pose, blendPose, blendAlpha, 'ARM_UPPER_LEFT_ROTATION'); armLowerRight.rotation = animateProperty(pose, blendPose, blendAlpha, 'ARM_LOWER_RIGHT_ROTATION', armLowerAngle); armLowerLeft.rotation = animateProperty(pose, blendPose, blendAlpha, 'ARM_LOWER_LEFT_ROTATION', armLowerAngle); legUpperRight.rotation = animateProperty(pose, blendPose, blendAlpha, 'LEG_UPPER_RIGHT_ROTATION'); legUpperLeft.rotation = animateProperty(pose, blendPose, blendAlpha, 'LEG_UPPER_LEFT_ROTATION'); legLowerRight.rotation = animateProperty(pose, blendPose, blendAlpha, 'LEG_LOWER_RIGHT_ROTATION'); legLowerLeft.rotation = animateProperty(pose, blendPose, blendAlpha, 'LEG_LOWER_LEFT_ROTATION'); footRight.rotation = animateProperty(pose, blendPose, blendAlpha, 'FOOT_RIGHT_ROTATION'); footLeft.rotation = animateProperty(pose, blendPose, blendAlpha, 'FOOT_LEFT_ROTATION'); } function pushAnimation(newAnimation, newBlendDecrement) { blendDecrement = newBlendDecrement; if (newAnimation !== animation) { blendAnimation = animation; animation = newAnimation; blendAlpha = 1; } } ; animate(0); }); var Player = ConfigContainer.expand(function (config) { var self = ConfigContainer.call(this, config); var speedFactor = PLAYER_SPEED_FACTOR_BASE; var stopped = false; var falling = false; var jumping = false; // If the player is currently jumping (and immune to gravity) var jumpAction = false; // Tracks tap releases var jumpStep = 0; // Tracks min/max jump heights var aerialSpeed = 0; // Actual vertical/air speed var baseY = config.y; var step = ROAD_STEP_DEFAULT; var nodeDistance = 0; var nodeTicks = 0; var nodeMulti = 0; var body = self.addChild(new PlayerBody({ y: -370 })); ; self.update = update; self.jumpStart = jumpStart; self.jumpEnd = jumpEnd; self.jumping = false; ; function update() { var nextNode = road.getNode(1); var currentNode = nextNode.previous; // Update horizontal movement var outputSpeed = PLAYER_SPEED_BASE * speedFactor; var distance = road.getNodeDist(); // Check for collision if (stopped && nextNode.step <= step) { stopped = false; } else if (nextNode.step > step && outputSpeed > distance) { road.rotate(distance - PLAYER_SPACING); speedFactor = PLAYER_SPEED_FACTOR_BASE; stopped = true; if (currentNode.step <= step) { body.pushAnimation(animationStand, PLAYER_POSE_TRANSITION); } } if (!stopped) { road.rotate(outputSpeed); if (!gameOver) { if (speedFactor < PLAYER_SPEED_FACTOR_MAX) { if ((speedFactor += PLAYER_SPEED_FACTOR_INCREMENT) >= PLAYER_SPEED_FACTOR_MAX) { speedFactor = PLAYER_SPEED_FACTOR_MAX; } } } else { if (speedFactor > 0) { if ((speedFactor -= PLAYER_SPEED_DECREMENT) <= 0) { speedFactor = 0; } } } } // TOOD: Get new node if applicable // Update vertical movement if (jumping) { jumpStep += aerialSpeed; if (!jumpAction && jumpStep >= PLAYER_JUMP_STEP_MIN || jumpStep >= PLAYER_JUMP_STEP_MAX) { falling = true; jumping = false; jumpAction = false; jumpStep = 0; } } else if (falling) { aerialSpeed -= PLAYER_GRAVITY; } else if (step > currentNode.step) { falling = true; body.pushAnimation(animationJump, PLAYER_POSE_TRANSITION); } step += aerialSpeed; if (falling && step <= currentNode.step) { step = currentNode.step; falling = false; aerialSpeed = 0; body.pushAnimation(stopped ? animationStand : animationRun, PLAYER_POSE_TRANSITION); } // Score calculations if (!gameOver && currentNode.distance > nodeDistance) { adjustScore(nodeMulti / nodeTicks); currentNode.distance = nodeDistance; nodeMulti = 0; nodeTicks = 0; } nodeMulti += stopped ? SCORE_STOPPED_FACTOR : speedFactor; nodeTicks++; // Adjustments var stepHeight = ROAD_STEP_HEIGHT_BASE + step * ROAD_STEP_HEIGHT_INCREMENT; // TODO: Better scaling self.y = baseY - stepHeight; // TODO: Better scaling self.scale.set(PLAYER_SCALE_BASE * stepHeight / ROAD_SEGMENT_HEIGHT); // TODO: Better scaling body.animate(PLAYER_ANIMATION_SPEED_BASE * speedFactor); multiplierText.setText((stopped ? SCORE_STOPPED_FACTOR : speedFactor).toFixed(1) + 'x'); } function jumpStart() { if (!gameOver && !jumping && !falling) { jumping = true; jumpAction = true; aerialSpeed = PLAYER_JUMP_STEP_INCREMENT; body.pushAnimation(animationJump, PLAYER_POSE_TRANSITION); } } function jumpEnd() { jumpAction = false; } function adjustScore(averageMulti) { var points = Math.floor(averageMulti * SCORE_SEGMENT_POINTS); score = Math.max(0, score + points); scoreText.setText(String(score).padStart(6, '0')); distanceText.setText((distanceRemaining -= SCORE_SEGMENT_DISTANCE) + 'm'); incrementText.setText((points === SCORE_MAX_POINTS ? '[MAX!] +' : '+') + points); if (distanceRemaining <= 0) { body.pushAnimation(animationStand, PLAYER_SPEED_DECREMENT / speedFactor); callGameOver(); } } ; body.pushAnimation(animationRun, PLAYER_POSE_TRANSITION); }); /** * config { * x : Number || 0, // See: ConfigContainer * y : Number || 0, // See: ConfigContainer * rotation : Number || 0, // See: ConfigContainer * anchorX : Number || 0, * anchorY : Number || 1, * size : Number || TEXT_DEFAULT_SIZE, * weight : Number || TEXT_DEFAULT_WEIGHT, * font : String || TEXT_DEFAULT_FONT, * fill : String || TEXT_DEFAULT_FILL, * border : String || TEXT_DEFAULT_BORDER, * } **/ var BorderedText = ConfigContainer.expand(function (text, config) { var self = ConfigContainer.call(this, config); config = config || {}; ; var anchorX = config.anchorX !== undefined ? config.anchorX : 0; var anchorY = config.anchorY !== undefined ? config.anchorY : 1; var size = config.size !== undefined ? config.size : TEXT_DEFAULT_SIZE; var weight = config.weight !== undefined ? config.weight : TEXT_DEFAULT_WEIGHT; var font = config.font !== undefined ? config.font : TEXT_DEFAULT_FONT; var textFill = config.fill !== undefined ? config.fill : TEXT_DEFAULT_FILL; var borderFill = config.border !== undefined ? config.border : TEXT_DEFAULT_BORDER; var textAssets = []; var mainAsset; ; self.setText = setText; self.setFill = setFill; ; function setText(newText) { for (var i = 0; i < textAssets.length; i++) { textAssets[i].setText(newText); } } function setFill(newFill) { textFill = newFill; mainAsset.fill = newFill; } function buildTextAssets(newText) { for (var i = 0; i < TEXT_OFFSETS.length; i++) { var main = i === TEXT_OFFSETS.length - 1; var fill = main ? textFill : borderFill; var textAsset = textAssets[i]; if (textAsset) { textAsset.destroy(); } textAsset = self.addChild(new Text2(newText, { fill: fill, font: font, size: size })); textAsset.anchor = { x: anchorX, y: anchorY }; // NOTE: Cannot be set in config textAsset.x = TEXT_OFFSETS[i][0] * weight; // NOTE: Cannot be set in config textAsset.y = TEXT_OFFSETS[i][1] * weight; // NOTE: Cannot be set in config textAssets[i] = textAsset; } mainAsset = textAssets[TEXT_OFFSETS.length - 1]; } ; buildTextAssets(text); return self; }); var Starfield = Container.expand(function (config) { var self = Container.call(this); config = config || {}; var starCount = config.starCount || 100; var starColor = config.starColor || 0xFFFFFF; var starSize = config.starSize || 2; for (var i = 0; i < starCount; i++) { var star = self.attachAsset('circle', { width: starSize, height: starSize, color: starColor, x: Math.random() * GAME_WIDTH, y: Math.random() * GAME_HEIGHT, anchorX: 0.5, anchorY: 0.5 }); } return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x121B20 // Sky blue color }); /**** * Game Code ****/ ; //============================================================================== // Global Constants & Settings //============================================================================== ; // Math Constants / Pre-calculations var MATH_4_PI = Math.PI * 4; var MATH_2_PI = Math.PI * 2; var MATH_HALF_PI = Math.PI / 2; var MATH_THIRD_PI = Math.PI / 3; var MATH_QUARTER_PI = Math.PI / 4; var MATH_FIFTH_PI = Math.PI / 5; var MATH_SIXTH_PI = Math.PI / 5; var MATH_EIGHTH_PI = Math.PI / 8; var MATH_HALF_ROOT_3 = Math.sqrt(3) / 2; // Required by: TEXT_OFFSETS, BorderedText, BorderedSymbol, BorderedShape, SymbolText ; // Text Settings var TEXT_OFFSETS = [[0, 1], [MATH_HALF_ROOT_3, 0.5], [MATH_HALF_ROOT_3, -0.5], [0, -1], [-MATH_HALF_ROOT_3, -0.5], [-MATH_HALF_ROOT_3, 0.5], [0, 0]]; // Required by: BorderedText, BorderedSymbol, BorderedShape, SymbolText var TEXT_DEFAULT_WEIGHT = 4; // Required by: BorderedText, BorderedSymbol, BorderedShape, SymbolText var TEXT_DEFAULT_BORDER = '#000000'; // Required by: BorderedText, BorderedSymbol, BorderedShape, SymbolText var TEXT_DEFAULT_FILL = '#FFFFFF'; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_FONT = 'Courier'; // Required by: BorderedText, SymbolText var TEXT_DEFAULT_SIZE = 80; // Required by: BorderedText, SymbolText ; // Game Constants var GAME_TICKS = 60; var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; ; // Road Constants var ROAD_SEGMENT_DISTANCE = 1.0; var ROAD_SEGMENT_POINTS = 100; var ROAD_SEGMENT_COUNT = 30; var ROAD_SEGMENT_ANGLE = MATH_2_PI / ROAD_SEGMENT_COUNT; var ROAD_SEGMENT_HEIGHT = 1000; var ROAD_SEGMENT_DESTROY = -2; var ROAD_SEGMENT_FADEOUT = 0.015; var ROAD_FREE_RUN_COUNT = 5; var ROAD_STEP_COUNT = 5; var ROAD_STEP_DEFAULT = 2; var ROAD_STEP_HEIGHT_BASE = 400; var ROAD_STEP_HEIGHT_INCREMENT = 80; var ROAD_STEP_CHANCE_BASE = 0.1; var ROAD_STEP_CHANCE_INCREMENT = 0.05; var ROAD_GEN_PLANT_ASSETS = 3; var ROAD_GEN_PLANT_MAX = 3; var ROAD_GEN_TREE_ASSETS = 4; var ROAD_GEN_TREE_CHANCE = 0.1; var ROAD_GEN_CLOUD_ASSETS = 4; var ROAD_GEN_CLOUD_CHANCE = 0.2; ; // Player Constants var PLAYER_SPACING = ROAD_SEGMENT_ANGLE / 8; // 1/8 of a segment var PLAYER_POSE_TRANSITION = 0.1; var PLAYER_GRAVITY = 0.02; var PLAYER_JUMP_STEP_MIN = 1.0; var PLAYER_JUMP_STEP_MAX = 2.0; var PLAYER_JUMP_STEP_INCREMENT = 0.15; var PLAYER_ANIMATION_SPEED_BASE = 0.02; var PLAYER_SCALE_BASE = 0.5; var PLAYER_SPEED_BASE = MATH_2_PI / (GAME_TICKS * 10); // 10s to complete a revolution var PLAYER_SPEED_FACTOR_BASE = 1.0; var PLAYER_SPEED_FACTOR_MAX = 1.5; var PLAYER_SPEED_FACTOR_INCREMENT = 0.001; var PLAYER_SPEED_DECREMENT = 0.01; ; // Scoring Constants var SCORE_TOTAL_DISTANCE = 500; var SCORE_SEGMENT_DISTANCE = 1; var SCORE_SEGMENT_POINTS = 100; var SCORE_STOPPED_FACTOR = -0.2; var SCORE_MAX_POINTS = SCORE_SEGMENT_POINTS * PLAYER_SPEED_FACTOR_MAX; //============================================================================== // Game Instances & Variables //============================================================================== ; // Variables var score = 0; var winningTime = 0; var gameOver = false; var distanceRemaining = SCORE_TOTAL_DISTANCE; ; // Instances var starfield = game.addChild(new Starfield({ starCount: 200, starColor: 0xFFFFFF, starSize: 2 })); var sun = game.addChild(new Sun({ x: GAME_WIDTH / 2, y: 50 })); var road = game.addChild(new Road({ x: GAME_WIDTH / 2, y: GAME_HEIGHT - GAME_WIDTH / 2 })); var player = game.addChild(new Player({ x: road.x, y: road.y, scale: 0.5 })); var distanceText = game.addChild(new BorderedText(distanceRemaining + 'm', { x: road.x, y: road.y - TEXT_DEFAULT_SIZE, anchorX: 0.5, anchorY: 1 })); var scoreText = game.addChild(new BorderedText('000000', { x: road.x, y: road.y, size: TEXT_DEFAULT_SIZE * 1.5, anchorX: 0.5, anchorY: 0.5 })); var multiplierText = game.addChild(new BorderedText('1.0x', { x: road.x, y: road.y + TEXT_DEFAULT_SIZE, anchorX: 0.5, anchorY: 0 })); var incrementText = game.addChild(new BorderedText('', { x: road.x - 300, y: road.y, anchorX: 1, anchorY: 0.5 })); var winningText = game.addChild(new BorderedText('', { x: GAME_WIDTH / 2, y: 500, anchorX: 0.5, anchorY: 0.5, size: 2 * TEXT_DEFAULT_SIZE })); ; //============================================================================== // Global events //============================================================================== ; game.down = player.jumpStart; game.up = player.jumpEnd; ; //============================================================================== // Global functions //============================================================================== ; // Helpers function callGameOver() { gameOver = true; winningTime = LK.ticks; LK.setScore(score); winningText.setText('Congratulations!'); // Check if winningTime is set and show game over screen after 60 ticks game.update = function () { if (winningTime && LK.ticks >= winningTime + 120) { LK.showGameOver(); } }; } ; // Animations & handlers function animateProperty(animationPose, blendPose, blendAlpha, key, baseValue) { var animationPoseValue = (animationPose || {})[key] || 0; var blendPoseValue = (blendPose || {})[key] || 0; return (baseValue || 0) + animationPoseValue * (1 - blendAlpha) + blendPoseValue * blendAlpha; } function animationRun(alpha) { // Animation constants var armUpperAngle = MATH_FIFTH_PI; var armLowerAngle = -5 * MATH_EIGHTH_PI; var legLowerAngle = MATH_EIGHTH_PI; // Sinusoidals var rightSinusoidal = Math.cos(MATH_2_PI * (alpha + 0.5)); var leftSinusoidal = Math.cos(MATH_2_PI * alpha); var doubleSinusoidal = Math.cos(MATH_4_PI * alpha); // Animation calculations var armUpperRightSwing = -rightSinusoidal * MATH_QUARTER_PI; var armUpperLeftSwing = -leftSinusoidal * MATH_QUARTER_PI; var legUpperRightSwing = rightSinusoidal * MATH_THIRD_PI; var legUpperLeftSwing = leftSinusoidal * MATH_THIRD_PI; return { BODY_OFFSET: doubleSinusoidal * 10, HEAD_ROTATION: (1 + doubleSinusoidal) * Math.PI / 32, ARM_UPPER_RIGHT_ROTATION: armUpperAngle + armUpperRightSwing, ARM_UPPER_LEFT_ROTATION: armUpperAngle + armUpperLeftSwing, ARM_LOWER_RIGHT_ROTATION: armLowerAngle + armUpperRightSwing / 2, ARM_LOWER_LEFT_ROTATION: armLowerAngle + armUpperLeftSwing / 2, LEG_UPPER_RIGHT_ROTATION: legUpperRightSwing, LEG_UPPER_LEFT_ROTATION: legUpperLeftSwing, LEG_LOWER_RIGHT_ROTATION: legLowerAngle + (alpha > 0.5 ? MATH_THIRD_PI + (1 - Math.abs(rightSinusoidal)) * MATH_SIXTH_PI : Math.abs(-legUpperRightSwing)), LEG_LOWER_LEFT_ROTATION: legLowerAngle + (alpha <= 0.5 ? MATH_THIRD_PI + (1 - Math.abs(leftSinusoidal)) * MATH_SIXTH_PI : Math.abs(-legUpperLeftSwing)), FOOT_RIGHT_ROTATION: Math.max(0, legUpperRightSwing * 2 / 3) - legLowerAngle, FOOT_LEFT_ROTATION: Math.max(0, legUpperLeftSwing * 2 / 3) - legLowerAngle }; } function animationJump(alpha) { var sinusoidal = Math.cos(MATH_2_PI * alpha); return animationRun(0.35 + sinusoidal * 0.02); } function animationStand(alpha) { var sinusoidal = Math.cos(MATH_2_PI * alpha); var offsetAngle = Math.PI / 16; var sharedAngle = (2 + sinusoidal) * Math.PI / 64; return { BODY_OFFSET: sinusoidal * 5, ARM_UPPER_RIGHT_ROTATION: 0.5 * offsetAngle, ARM_UPPER_LEFT_ROTATION: 3 * offsetAngle, ARM_LOWER_RIGHT_ROTATION: -4 * offsetAngle, ARM_LOWER_LEFT_ROTATION: -4 * offsetAngle, LEG_UPPER_RIGHT_ROTATION: 1.5 * offsetAngle - sharedAngle, LEG_UPPER_LEFT_ROTATION: -1.5 * offsetAngle - sharedAngle, LEG_LOWER_RIGHT_ROTATION: 2 * sharedAngle, LEG_LOWER_LEFT_ROTATION: 2 * sharedAngle, FOOT_RIGHT_ROTATION: -sharedAngle - 1.5 * offsetAngle, FOOT_LEFT_ROTATION: -sharedAngle + 1.5 * offsetAngle }; }
===================================================================
--- original.js
+++ change.js
@@ -44,9 +44,10 @@
self.update = update;
;
function update() {
if (LK.ticks % 30 == 0) {
- sunAsset.scale.x *= -1;
+ //sunAsset.scale.x *= -1;
+ //TODO Other animation
}
}
});
var RoadSegment = ConfigContainer.expand(function (config) {
white
circle sliced into many pieces, flat image. 2d, white background, shadowless.
pixel art of a tall, tree. game asset, 2d, white background, shadowless.
pixel art cloud. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
dark space.
flying lava bubble. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a bonus crystal ball with the recycle symbol. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
top view A green round start button empty in the center like a ring.