@@ -1057,34 +1057,61 @@ function getDifficultyPlatformSpacing(): number {
10571057 }
10581058}
10591059
1060- function getDifficultyMovementRange ( ) : number {
1061- // Gradually increase how far platforms move
1062- // At score 0: 2-3 range
1063- // At score 20: 2-4 range
1064- // At score 40+: 2-5 range (cap)
1065- const baseRange = Math . min ( 5 , 3 + ( gameState . score / 40 ) * 2 ) ;
1066- const minRange = 2 ;
1067- return minRange + Math . random ( ) * ( baseRange - minRange ) ;
1068- }
1060+
10691061
10701062function getDifficultyPlatformCubeCount ( ) : number {
1071- // Gradually decrease number of cubes to make precision more important
1072- // At score 0: 4 cubes (easy)
1073- // At score 25: 3 cubes
1074- // At score 50+: 2 cubes (cap - still reasonable)
1063+ // Gradually blend cube counts using probability-based selection
1064+ // More natural transition from mostly 4 cubes to mostly 3, then mostly 2, then some 1
10751065 const score = gameState . score ;
1066+ const random = Math . random ( ) ;
10761067
1077- if ( score <= 25 ) {
1078- // Score 0-25: 4 to 3 cubes
1079- const t = score / 25 ;
1080- return Math . floor ( 4 - t * 1 ) ; // 4 to 3
1081- } else if ( score <= 50 ) {
1082- // Score 25-50: 3 to 2 cubes
1083- const t = ( score - 25 ) / 25 ;
1084- return Math . floor ( 3 - t * 1 ) ; // 3 to 2
1068+ if ( score <= 10 ) {
1069+ // Score 0-10: Mostly 4 cubes (80%), some 3 cubes (20%)
1070+ const chance4 = 0.8 - ( score / 10 ) * 0.3 ; // 80% to 50%
1071+ const chance3 = 1 - chance4 ; // 20% to 50%
1072+
1073+ if ( random < chance4 ) return 4 ;
1074+ else return 3 ;
1075+ } else if ( score <= 25 ) {
1076+ // Score 10-25: Mix of 4 and 3, trending toward 3
1077+ const t = ( score - 10 ) / ( 25 - 10 ) ;
1078+ const chance4 = 0.5 - t * 0.4 ; // 50% to 10%
1079+ const chance3 = 1 - chance4 ; // 50% to 90%
1080+
1081+ if ( random < chance4 ) return 4 ;
1082+ else return 3 ;
1083+ } else if ( score <= 40 ) {
1084+ // Score 25-40: Mostly 3 cubes, some 2 cubes starting to appear
1085+ const t = ( score - 25 ) / ( 40 - 25 ) ;
1086+ const chance3 = 0.9 - t * 0.4 ; // 90% to 50%
1087+ const chance2 = 1 - chance3 ; // 10% to 50%
1088+
1089+ if ( random < chance3 ) return 3 ;
1090+ else return 2 ;
1091+ } else if ( score <= 60 ) {
1092+ // Score 40-60: Mix of 3 and 2, trending toward 2
1093+ const t = ( score - 40 ) / ( 60 - 40 ) ;
1094+ const chance3 = 0.5 - t * 0.4 ; // 50% to 10%
1095+ const chance2 = 1 - chance3 ; // 50% to 90%
1096+
1097+ if ( random < chance3 ) return 3 ;
1098+ else return 2 ;
1099+ } else if ( score <= 80 ) {
1100+ // Score 60-80: Mostly 2 cubes, some 1 cube starting to appear
1101+ const t = ( score - 60 ) / ( 80 - 60 ) ;
1102+ const chance2 = 0.9 - t * 0.4 ; // 90% to 50%
1103+ const chance1 = 1 - chance2 ; // 10% to 50%
1104+
1105+ if ( random < chance2 ) return 2 ;
1106+ else return 1 ;
10851107 } else {
1086- // Score 50+: cap at 2 cubes
1087- return 2 ;
1108+ // Score 80+: Mix of 2 and 1, trending toward 1 (extreme difficulty)
1109+ const t = Math . min ( 1 , ( score - 80 ) / 40 ) ; // Cap progression at score 120
1110+ const chance2 = 0.5 - t * 0.3 ; // 50% to 20%
1111+ const chance1 = 1 - chance2 ; // 50% to 80%
1112+
1113+ if ( random < chance2 ) return 2 ;
1114+ else return 1 ;
10881115 }
10891116}
10901117
@@ -1203,29 +1230,22 @@ function createPlatform(x: number, y: number) {
12031230
12041231 // Get current difficulty-based properties
12051232 const movementSpeed = getDifficultyMovementSpeed ( ) ;
1206- let movementRange = getDifficultyMovementRange ( ) ;
12071233 const cubeCount = getDifficultyPlatformCubeCount ( ) ;
1208-
1209- // Each cube is 1x1x1 unit
1210- const cubeSize = 1 ;
1211- const cubeSpacing = 1.1 ; // Smaller gap between cubes
1212- const platformWidth = cubeCount * cubeSpacing ;
1213-
1214- // Calculate viewport bounds to ensure movement range doesn't exceed visible area
1234+
1235+ // Calculate full viewport width for movement range
12151236 const viewportHalfWidth =
12161237 camera . aspect *
12171238 Math . tan ( THREE . MathUtils . degToRad ( camera . fov / 2 ) ) *
12181239 camera . position . z ;
1240+ const movementRange = viewportHalfWidth * 2 ;
12191241
1220- const platformHalfWidth = platformWidth / 2 ;
1221- const maxAllowedRange = Math . min (
1222- movementRange ,
1223- Math . abs ( x - ( - viewportHalfWidth + platformHalfWidth ) ) , // Distance to left edge
1224- Math . abs ( x - ( viewportHalfWidth - platformHalfWidth ) ) // Distance to right edge
1225- ) ;
1242+ // Each cube is 1x1x1 unit
1243+ const cubeSize = 1 ;
1244+ const cubeSpacing = 1.1 ; // Smaller gap between cubes
1245+ const platformWidth = cubeCount * cubeSpacing ;
12261246
1227- // Ensure we have at least some movement range, but not more than viewport allows
1228- movementRange = Math . max ( 0.5 , maxAllowedRange ) ;
1247+ // Movement range is already calculated as full viewport width in getDifficultyMovementRange()
1248+ // Runtime bounds checking in updateGame() will handle keeping platforms on screen
12291249
12301250 // Use global counter for consistent indexing across all platforms ever created
12311251 const platformIndex = globalPlatformCounter ++ ;
0 commit comments