User prompt
Haz que la paredes no tengan textura
User prompt
Haz que la pared tenga el color de la imagen
User prompt
También pon un reconocimiento de cada ves que se toca la pared para poner colision con esta
User prompt
Debes usar una textura cuadrada has que la textura de la pared se pueda moldear para el juego
User prompt
Crea 2 texturas 1 invisible que sea para la segunda textura que es donde está la visible se usará la invisible para moldear la pared y con la textura mostrada se pegará a la que lo se ve
User prompt
Por las coordenadas crea paredes y haz o fuerza que la textura se moldé a la base de la coordenada
User prompt
Haz que la pared sea 1 sola por cada lugar de pared
User prompt
Haz un sistema propio de paredes para que imiten a las de baldi's basic education
User prompt
No se como hacer las paredes te dejo a consideración tuya hacer un sistema de paredes funcional
User prompt
En el techo haz cuadrados amarillos que estén en el medio o en un lugar que no esté serca de una esquina
User prompt
Haz que se pueda interactuar con la configuraciónes y haz el botón de este más grande
User prompt
Haz un sistema de configuración en la parte superior en la derecha para configurar la sensibilidad esta tendrá del 0 al 100 en esta pon diferente sensibilidad para el gusto del jugador ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Haz que el movimiento de la cámara más fluido ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Con el sistema de coordenadas trasa donde hay paredes y donde adra y pon una pared las paredes no se podrán acumular en un lugar se van a poner una pared al terminar el cuadrado asi hasta completar una línea
User prompt
Has que la paredes sigan una línea recta
User prompt
Haz un sistema de vista para que las paredes no se intercalan ósea si tengo una pared enfrente no puedo ver las cosas que están detrás de esta
User prompt
Haz que la pared sea un cuadrado
User prompt
Haz que las paredes sigan una coordenada para que no se vean tan puntiagudas
User prompt
Haz que el movimiento del personaje disminuya
User prompt
Haz que el juego separe por el sistema de paeudeo-3D las paredes la parte del medio el piso la parte inferior y el techo la parte alta de este como en doom
User prompt
Haz una textura que se llame piso y repréntala con color verde y ponla en la coordenada 0
User prompt
Haz que el personaje no pueda bajar de la coordenada y 0
User prompt
Haz visibles las coordenadas x y z para el jugar
User prompt
has un sistema de coordenadas y que las paredes piso y techo respeten estas coordenadas
User prompt
Haz un espacio para estas áreas el piso siempre va a estar debajo del personaje y de las paredes las paredes están en el medio del piso y el techo es un separador de área y el techo simpre va a estar arriba del personaje y arriba de las paredes
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CeilingTileRenderer = Container.expand(function () {
var self = Container.call(this);
self.tiles = [];
// Generate ceiling tiles in safe positions (away from corners and walls)
self.generateTiles = function () {
for (var x = 2; x < worldGrid.width - 2; x++) {
for (var y = 2; y < worldGrid.height - 2; y++) {
// Only place tiles in open areas (not near walls or corners)
if (!worldGrid.hasWallAt(x * worldGrid.cellSize, y * worldGrid.cellSize) && !self.isNearCorner(x, y) && self.isSafePosition(x, y)) {
var tile = {
worldX: x * worldGrid.cellSize + worldGrid.cellSize / 2,
worldY: y * worldGrid.cellSize + worldGrid.cellSize / 2,
sprite: null
};
self.tiles.push(tile);
}
}
}
};
// Check if position is near a corner
self.isNearCorner = function (gridX, gridY) {
// Check 3x3 area around position for wall density
var wallCount = 0;
for (var dx = -1; dx <= 1; dx++) {
for (var dy = -1; dy <= 1; dy++) {
var checkX = gridX + dx;
var checkY = gridY + dy;
if (checkX >= 0 && checkX < worldGrid.width && checkY >= 0 && checkY < worldGrid.height) {
if (worldGrid.walls[checkX][checkY]) {
wallCount++;
}
}
}
}
return wallCount >= 3; // Near corner if 3+ walls nearby
};
// Check if position is safe (center of open areas)
self.isSafePosition = function (gridX, gridY) {
// Ensure there's open space in all 4 cardinal directions
var directions = [{
x: 0,
y: -1
}, {
x: 1,
y: 0
}, {
x: 0,
y: 1
}, {
x: -1,
y: 0
}];
for (var i = 0; i < directions.length; i++) {
var checkX = gridX + directions[i].x;
var checkY = gridY + directions[i].y;
if (checkX >= 0 && checkX < worldGrid.width && checkY >= 0 && checkY < worldGrid.height) {
if (worldGrid.walls[checkX][checkY]) {
return false;
}
}
}
return true;
};
self.render = function (player) {
// Clear existing sprites
for (var i = 0; i < self.tiles.length; i++) {
if (self.tiles[i].sprite) {
self.tiles[i].sprite.visible = false;
}
}
var visibleTiles = [];
// Calculate which tiles are visible and their screen positions
for (var i = 0; i < self.tiles.length; i++) {
var tile = self.tiles[i];
var dx = tile.worldX - player.x;
var dy = tile.worldY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Only render tiles within reasonable distance
if (distance < 800) {
// Calculate angle relative to player's view direction
var tileAngle = Math.atan2(dy, dx);
var angleDiff = tileAngle - player.angle;
// Normalize angle difference
while (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
while (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;
// Check if tile is within field of view
var fov = Math.PI / 3;
if (Math.abs(angleDiff) < fov / 2) {
// Calculate screen X position
var screenX = 1024 + angleDiff / (fov / 2) * 1024;
if (screenX >= 0 && screenX <= 2048) {
visibleTiles.push({
tile: tile,
distance: distance,
screenX: screenX,
screenY: 400 - 200 * (1000 / (distance + 100)) // Project to ceiling
});
}
}
}
}
// Sort by distance (farthest first)
visibleTiles.sort(function (a, b) {
return b.distance - a.distance;
});
// Render visible tiles
for (var i = 0; i < visibleTiles.length; i++) {
var visibleTile = visibleTiles[i];
var tile = visibleTile.tile;
if (!tile.sprite) {
tile.sprite = self.addChild(LK.getAsset('ceilingTile', {
anchorX: 0.5,
anchorY: 0.5
}));
}
tile.sprite.x = visibleTile.screenX;
tile.sprite.y = visibleTile.screenY;
tile.sprite.visible = true;
// Scale based on distance
var scale = Math.max(0.1, 20 / (visibleTile.distance + 20));
tile.sprite.scaleX = scale;
tile.sprite.scaleY = scale;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.x = 1024;
self.y = 1366;
self.angle = 0;
self.speed = 3;
self.rotSpeed = 0.1;
// Smooth interpolation properties
self.targetX = 1024;
self.targetY = 1366;
self.targetAngle = 0;
self.smoothingFactor = 0.15;
// Player visual for debugging (will be hidden in first person)
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
playerGraphics.visible = false; // Hide for first person view
self.moveForward = function () {
var newX = self.targetX + Math.cos(self.targetAngle) * self.speed;
var newY = self.targetY + Math.sin(self.targetAngle) * self.speed;
// Constrain Y coordinate to not go below 0
if (newY < 0) {
newY = 0;
}
// Check collision with world grid using improved collision detection
if (!worldGrid.checkCollision(newX, newY)) {
self.targetX = newX;
self.targetY = newY;
}
};
self.moveBackward = function () {
var newX = self.targetX - Math.cos(self.targetAngle) * self.speed;
var newY = self.targetY - Math.sin(self.targetAngle) * self.speed;
// Constrain Y coordinate to not go below 0
if (newY < 0) {
newY = 0;
}
// Check collision with world grid using improved collision detection
if (!worldGrid.checkCollision(newX, newY)) {
self.targetX = newX;
self.targetY = newY;
}
};
self.turnLeft = function () {
self.targetAngle -= self.rotSpeed;
};
self.turnRight = function () {
self.targetAngle += self.rotSpeed;
};
self.updateSmooth = function () {
// Smooth interpolation for position
self.x += (self.targetX - self.x) * self.smoothingFactor;
self.y += (self.targetY - self.y) * self.smoothingFactor;
// Smooth interpolation for rotation with angle wrapping
var angleDiff = self.targetAngle - self.angle;
// Handle angle wrapping (ensure shortest rotation path)
if (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
if (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;
self.angle += angleDiff * self.smoothingFactor;
};
return self;
});
var Renderer3D = Container.expand(function () {
var self = Container.call(this);
self.wallColumns = [];
self.floorColumns = [];
self.ceilingColumns = [];
self.zBuffer = []; // Track depth for each column
// Create pseudo-3D rendering columns
for (var i = 0; i < 512; i++) {
var wallCol = self.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 1.0
}));
wallCol.x = i * 4;
wallCol.y = 1366;
self.wallColumns.push(wallCol);
var floorCol = self.addChild(LK.getAsset('piso', {
anchorX: 0.5,
anchorY: 0.5
}));
floorCol.x = i * 4;
floorCol.y = 1366;
self.floorColumns.push(floorCol);
var ceilCol = self.addChild(LK.getAsset('ceilingStrip', {
anchorX: 0.5,
anchorY: 0.5
}));
ceilCol.x = i * 4;
ceilCol.y = 700;
self.ceilingColumns.push(ceilCol);
}
self.render = function (player) {
var fov = Math.PI / 3; // 60 degrees field of view
var halfFov = fov / 2;
var screenHeight = 2732;
var screenCenter = screenHeight / 2; // Center line at Y = 1366
// Store column data for depth sorting
var columnData = [];
for (var i = 0; i < 512; i++) {
var rayAngle = player.angle - halfFov + i / 512 * fov;
var rayData = self.castRayWithCoords(player.x, player.y, rayAngle);
var distance = rayData.distance;
var hitX = rayData.hitX;
var hitY = rayData.hitY;
// Store column data with distance for sorting
columnData.push({
index: i,
distance: distance,
hitX: hitX,
hitY: hitY,
rayAngle: rayAngle
});
}
// Sort columns by distance (farthest first for proper depth)
columnData.sort(function (a, b) {
return b.distance - a.distance;
});
// Initialize z-buffer for this frame
for (var k = 0; k < 512; k++) {
self.zBuffer[k] = 1000; // Start with maximum distance
}
// First pass: Update z-buffer with closest distances
for (var j = 0; j < columnData.length; j++) {
var data = columnData[j];
var i = data.index;
var distance = data.distance;
// Only update z-buffer if this is closer
if (distance < self.zBuffer[i]) {
self.zBuffer[i] = distance;
}
}
// Second pass: Render only if at closest distance
for (var j = 0; j < columnData.length; j++) {
var data = columnData[j];
var i = data.index;
var distance = data.distance;
var hitX = data.hitX;
var hitY = data.hitY;
// Only render if this column is at the closest distance
if (Math.abs(distance - self.zBuffer[i]) < 1) {
// Calculate wall height using square texture molding
var baseWallSize = worldGrid.cellSize; // Use grid cell size as base
var wallHeight = Math.max(100, baseWallSize * (800 / (distance + 100)));
var wallWidth = 8; // Column width for raycasting display
var halfWallHeight = wallHeight / 2;
// WALLS: Position in middle section (centered on screen)
var wallTop = screenCenter - halfWallHeight;
var wallBottom = screenCenter + halfWallHeight;
// Mold square texture to fit coordinate-based dimensions
self.wallColumns[i].height = wallHeight;
self.wallColumns[i].width = wallWidth;
self.wallColumns[i].y = wallBottom; // Anchor at bottom of wall
self.wallColumns[i].visible = false; // Remove wall texture
// Apply texture coordinate molding based on hit position
var gridX = Math.floor(hitX / worldGrid.cellSize);
var gridY = Math.floor(hitY / worldGrid.cellSize);
// Calculate texture offset within the grid cell for seamless tiling
var textureOffsetX = hitX % worldGrid.cellSize / worldGrid.cellSize;
var textureOffsetY = hitY % worldGrid.cellSize / worldGrid.cellSize;
// Mold the square texture to align with coordinate boundaries
// Apply texture UV mapping simulation through positioning
var columnOffset = textureOffsetX * wallWidth;
self.wallColumns[i].x = i * 4 + columnOffset;
// Apply coordinate-based texture variation for visual distinction
var coordHash = (gridX + gridY) % 3;
switch (coordHash) {
case 0:
self.wallColumns[i].tint = 0x16ae31;
break;
// Original green
case 1:
self.wallColumns[i].tint = 0x26be41;
break;
// Lighter green
case 2:
self.wallColumns[i].tint = 0x069e21;
break;
// Darker green
}
// FLOOR: Bottom section (from wall bottom to screen bottom)
var floorTop = wallBottom;
var floorHeight = screenHeight - floorTop;
self.floorColumns[i].y = floorTop + floorHeight / 2; // Center floor in bottom section
self.floorColumns[i].height = Math.max(2, floorHeight);
self.floorColumns[i].visible = true;
// CEILING: Top section (from screen top to wall top)
var ceilingHeight = wallTop;
self.ceilingColumns[i].y = ceilingHeight / 2; // Center ceiling in top section
self.ceilingColumns[i].height = Math.max(2, ceilingHeight);
self.ceilingColumns[i].visible = true;
} else {
// Hide columns that are behind walls
self.wallColumns[i].visible = false;
self.floorColumns[i].visible = false;
self.ceilingColumns[i].visible = false;
}
}
};
self.castRay = function (startX, startY, angle) {
var rayData = self.castRayWithCoords(startX, startY, angle);
return rayData.distance;
};
self.castRayWithCoords = function (startX, startY, angle) {
var rayX = startX;
var rayY = startY;
var deltaX = Math.cos(angle) * 2;
var deltaY = Math.sin(angle) * 2;
var distance = 0;
// Raycast using world coordinate system
while (distance < 1000) {
rayX += deltaX;
rayY += deltaY;
distance += 2;
// Check for walls using world grid
if (worldGrid.hasWallAt(rayX, rayY)) {
break;
}
}
// Align hit coordinates to grid boundaries for straight walls
var gridX = Math.floor(rayX / worldGrid.cellSize);
var gridY = Math.floor(rayY / worldGrid.cellSize);
var alignedHitX = gridX * worldGrid.cellSize;
var alignedHitY = gridY * worldGrid.cellSize;
return {
distance: distance,
hitX: alignedHitX,
hitY: alignedHitY
};
};
return self;
});
var SensitivityConfig = Container.expand(function () {
var self = Container.call(this);
// Load saved sensitivity or default to 50
self.sensitivity = storage.sensitivity || 50;
self.isVisible = false;
// Create background panel
var background = self.addChild(LK.getAsset('untexturedArea', {
anchorX: 0,
anchorY: 0,
width: 300,
height: 200,
alpha: 0.8
}));
background.tint = 0x222222;
// Create title text
var titleText = new Text2('Sensitivity', {
size: 40,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
titleText.x = 150;
titleText.y = 20;
self.addChild(titleText);
// Create sensitivity value text
var valueText = new Text2(self.sensitivity.toString(), {
size: 35,
fill: 0xFFFFFF
});
valueText.anchor.set(0.5, 0);
valueText.x = 150;
valueText.y = 70;
self.addChild(valueText);
// Create decrease button (larger for mobile)
var decreaseBtn = self.addChild(LK.getAsset('untexturedArea', {
anchorX: 0.5,
anchorY: 0.5,
width: 70,
height: 60
}));
decreaseBtn.x = 80;
decreaseBtn.y = 130;
decreaseBtn.tint = 0x666666;
var decreaseText = new Text2('-', {
size: 40,
fill: 0xFFFFFF
});
decreaseText.anchor.set(0.5, 0.5);
decreaseText.x = 80;
decreaseText.y = 130;
self.addChild(decreaseText);
// Create increase button (larger for mobile)
var increaseBtn = self.addChild(LK.getAsset('untexturedArea', {
anchorX: 0.5,
anchorY: 0.5,
width: 70,
height: 60
}));
increaseBtn.x = 220;
increaseBtn.y = 130;
increaseBtn.tint = 0x666666;
var increaseText = new Text2('+', {
size: 40,
fill: 0xFFFFFF
});
increaseText.anchor.set(0.5, 0.5);
increaseText.x = 220;
increaseText.y = 130;
self.addChild(increaseText);
// Update sensitivity display
self.updateDisplay = function () {
valueText.setText(self.sensitivity.toString());
// Save to storage
storage.sensitivity = self.sensitivity;
};
// Toggle visibility
self.toggle = function () {
self.isVisible = !self.isVisible;
self.visible = self.isVisible;
};
// Handle decrease button with visual feedback
decreaseBtn.down = function (x, y, obj) {
decreaseBtn.tint = 0x888888; // Lighten on press
if (self.sensitivity > 0) {
self.sensitivity = Math.max(0, self.sensitivity - 5);
self.updateDisplay();
}
};
decreaseBtn.up = function (x, y, obj) {
decreaseBtn.tint = 0x666666; // Reset color on release
};
// Handle increase button with visual feedback
increaseBtn.down = function (x, y, obj) {
increaseBtn.tint = 0x888888; // Lighten on press
if (self.sensitivity < 100) {
self.sensitivity = Math.min(100, self.sensitivity + 5);
self.updateDisplay();
}
};
increaseBtn.up = function (x, y, obj) {
increaseBtn.tint = 0x666666; // Reset color on release
};
// Add background click handler to prevent game interactions
background.down = function (x, y, obj) {
// Prevent event from bubbling to game
return true;
};
background.up = function (x, y, obj) {
// Prevent event from bubbling to game
return true;
};
background.move = function (x, y, obj) {
// Prevent event from bubbling to game
return true;
};
// Initially hidden
self.visible = false;
return self;
});
var WallRenderer = Container.expand(function () {
var self = Container.call(this);
self.wallSegments = [];
// Generate coordinate-based walls with proper texture alignment
self.generateWalls = function () {
// Clear existing walls
for (var i = 0; i < self.wallSegments.length; i++) {
if (self.wallSegments[i].sprite) {
self.wallSegments[i].sprite.destroy();
}
if (self.wallSegments[i].moldSprite) {
self.wallSegments[i].moldSprite.destroy();
}
}
self.wallSegments = [];
// Create individual wall segments for each grid coordinate with walls
for (var x = 0; x < worldGrid.width; x++) {
for (var y = 0; y < worldGrid.height; y++) {
if (worldGrid.walls[x][y]) {
// Create wall segment aligned to exact grid coordinates
var wallSegment = {
gridX: x,
gridY: y,
worldX: x * worldGrid.cellSize,
worldY: y * worldGrid.cellSize,
width: worldGrid.cellSize,
height: worldGrid.cellSize,
sprite: null,
moldSprite: null,
lastVisible: false
};
self.wallSegments.push(wallSegment);
}
}
}
};
// Render walls with coordinate-based texture alignment
self.render = function (player) {
var fov = Math.PI / 3; // 60 degrees field of view
var maxDistance = 1000;
// Sort walls by distance for proper depth rendering
var visibleWalls = [];
for (var i = 0; i < self.wallSegments.length; i++) {
var wall = self.wallSegments[i];
// Calculate distance from player to wall center
var wallCenterX = wall.worldX + wall.width / 2;
var wallCenterY = wall.worldY + wall.height / 2;
var dx = wallCenterX - player.x;
var dy = wallCenterY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Only process walls within reasonable distance
if (distance < maxDistance) {
// Calculate angle relative to player's view direction
var wallAngle = Math.atan2(dy, dx);
var angleDiff = wallAngle - player.angle;
// Normalize angle difference
while (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
while (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;
// Check if wall is within field of view (with some margin)
if (Math.abs(angleDiff) < fov / 2 + 0.5) {
visibleWalls.push({
wall: wall,
distance: distance,
angleDiff: angleDiff,
wallCenterX: wallCenterX,
wallCenterY: wallCenterY
});
}
}
// Hide walls that are too far or out of view
if (wall.sprite && (distance >= maxDistance || Math.abs(angleDiff) >= fov / 2 + 0.5)) {
wall.sprite.visible = false;
if (wall.moldSprite) {
wall.moldSprite.visible = false;
}
wall.lastVisible = false;
}
}
// Sort visible walls by distance (farthest first)
visibleWalls.sort(function (a, b) {
return b.distance - a.distance;
});
// Render visible walls with coordinate-aligned textures
for (var i = 0; i < visibleWalls.length; i++) {
var visibleWall = visibleWalls[i];
var wall = visibleWall.wall;
var distance = visibleWall.distance;
var angleDiff = visibleWall.angleDiff;
// Create sprite if it doesn't exist
if (!wall.sprite) {
// Create invisible mold texture for shape molding
wall.moldSprite = self.addChild(LK.getAsset('invisibleWallMold', {
anchorX: 0.5,
anchorY: 0.5
}));
wall.moldSprite.alpha = 0; // Make completely invisible
// Create visible texture that will align to the mold
wall.sprite = self.addChild(LK.getAsset('baldiWall', {
anchorX: 0.5,
anchorY: 0.5
}));
}
// Calculate screen position based on wall center
var screenX = 1024 + angleDiff / (fov / 2) * 1024;
var screenY = 1366; // Center height
// Calculate size based on distance and force texture to fit coordinate bounds
var baseSize = worldGrid.cellSize;
var sizeScale = Math.max(0.1, 400 / (distance + 100));
var wallWidth = Math.max(20, baseSize * sizeScale);
var wallHeight = Math.max(20, baseSize * sizeScale);
// Position invisible mold sprite aligned to exact coordinate system
wall.moldSprite.x = screenX;
wall.moldSprite.y = screenY;
wall.moldSprite.width = wallWidth;
wall.moldSprite.height = wallHeight;
wall.moldSprite.visible = false; // Keep invisible
// Position visible wall sprite to align with the mold
wall.sprite.x = wall.moldSprite.x;
wall.sprite.y = wall.moldSprite.y;
wall.sprite.width = wall.moldSprite.width;
wall.sprite.height = wall.moldSprite.height;
wall.sprite.visible = false; // Remove wall texture
wall.lastVisible = true;
// Force texture alignment to coordinate boundaries
// Calculate texture offset based on exact grid position
var textureOffsetX = wall.gridX % 2 * 0.5;
var textureOffsetY = wall.gridY % 2 * 0.5;
// Remove tinting to show original wall image colors
wall.sprite.tint = 0xFFFFFF; // Use original image colors
// Add depth-based transparency
var alpha = Math.max(0.3, 1.0 - distance / maxDistance);
wall.sprite.alpha = alpha;
// Add coordinate-based texture stripes for visual alignment
if (!wall.sprite.stripe) {
wall.sprite.stripe = self.addChild(LK.getAsset('baldiWallStripe', {
anchorX: 0.5,
anchorY: 0.5
}));
}
// Position stripe aligned to coordinate system
wall.sprite.stripe.x = screenX;
wall.sprite.stripe.y = screenY - wallHeight * 0.3;
wall.sprite.stripe.width = wallWidth;
wall.sprite.stripe.height = Math.max(4, wallHeight * 0.1);
wall.sprite.stripe.visible = false; // Remove wall stripe texture
wall.sprite.stripe.alpha = alpha * 0.8;
}
};
return self;
});
/****
* Initialize Game
****/
// Create player
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// World coordinate system - grid-based layout
var worldGrid = {
cellSize: 200,
width: 20,
// 20x20 grid
height: 20,
walls: [],
// Will store wall positions
// Initialize world grid with walls
initializeGrid: function initializeGrid() {
for (var x = 0; x < this.width; x++) {
this.walls[x] = [];
for (var y = 0; y < this.height; y++) {
// Create backrooms-style layout
var isWall = false;
// Outer boundaries are always walls
if (x === 0 || x === this.width - 1 || y === 0 || y === this.height - 1) {
isWall = true;
}
// Create maze-like structure typical of backrooms
else if (x % 3 === 0 && y % 3 === 0 || x % 4 === 0 && y % 2 === 0 || y % 4 === 0 && x % 2 === 0) {
isWall = true;
}
this.walls[x][y] = isWall;
}
}
},
// Check if a world position has a wall
hasWallAt: function hasWallAt(worldX, worldY) {
var gridX = Math.floor(worldX / this.cellSize);
var gridY = Math.floor(worldY / this.cellSize);
if (gridX < 0 || gridX >= this.width || gridY < 0 || gridY >= this.height) {
return true; // Outside bounds = wall
}
return this.walls[gridX][gridY];
},
// Check collision with wall boundaries (with player radius)
checkCollision: function checkCollision(worldX, worldY, radius) {
radius = radius || 20; // Default player radius
var gridX = Math.floor(worldX / this.cellSize);
var gridY = Math.floor(worldY / this.cellSize);
// Check the four corners of the player's bounding box
var corners = [{
x: worldX - radius,
y: worldY - radius
}, {
x: worldX + radius,
y: worldY - radius
}, {
x: worldX - radius,
y: worldY + radius
}, {
x: worldX + radius,
y: worldY + radius
}];
for (var i = 0; i < corners.length; i++) {
var corner = corners[i];
var cornerGridX = Math.floor(corner.x / this.cellSize);
var cornerGridY = Math.floor(corner.y / this.cellSize);
// Check bounds
if (cornerGridX < 0 || cornerGridX >= this.width || cornerGridY < 0 || cornerGridY >= this.height) {
return true;
}
// Check wall collision
if (this.walls[cornerGridX][cornerGridY]) {
return true;
}
}
return false;
},
// Convert screen coordinates to world coordinates
screenToWorld: function screenToWorld(screenX, screenY) {
return {
x: screenX,
y: screenY
};
},
// Convert world coordinates to screen coordinates
worldToScreen: function worldToScreen(worldX, worldY) {
return {
x: worldX,
y: worldY
};
}
};
// Initialize the world grid
worldGrid.initializeGrid();
// Add wall line completion system
worldGrid.completeWallLines = function () {
// Trace horizontal lines and complete them
for (var y = 0; y < this.height; y++) {
var wallStart = -1;
var wallEnd = -1;
// Find wall segments in this row
for (var x = 0; x < this.width; x++) {
if (this.walls[x][y]) {
if (wallStart === -1) {
wallStart = x; // Start of wall segment
}
wallEnd = x; // Update end of wall segment
} else {
// If we found a wall segment, complete the line between start and end
if (wallStart !== -1 && wallEnd !== -1 && wallEnd > wallStart) {
for (var fillX = wallStart; fillX <= wallEnd; fillX++) {
this.walls[fillX][y] = true; // Fill the gap
}
}
wallStart = -1; // Reset for next segment
wallEnd = -1;
}
}
// Complete any remaining segment at end of row
if (wallStart !== -1 && wallEnd !== -1 && wallEnd > wallStart) {
for (var fillX = wallStart; fillX <= wallEnd; fillX++) {
this.walls[fillX][y] = true;
}
}
}
// Trace vertical lines and complete them
for (var x = 0; x < this.width; x++) {
var wallStart = -1;
var wallEnd = -1;
// Find wall segments in this column
for (var y = 0; y < this.height; y++) {
if (this.walls[x][y]) {
if (wallStart === -1) {
wallStart = y; // Start of wall segment
}
wallEnd = y; // Update end of wall segment
} else {
// If we found a wall segment, complete the line between start and end
if (wallStart !== -1 && wallEnd !== -1 && wallEnd > wallStart) {
for (var fillY = wallStart; fillY <= wallEnd; fillY++) {
this.walls[x][fillY] = true; // Fill the gap
}
}
wallStart = -1; // Reset for next segment
wallEnd = -1;
}
}
// Complete any remaining segment at end of column
if (wallStart !== -1 && wallEnd !== -1 && wallEnd > wallStart) {
for (var fillY = wallStart; fillY <= wallEnd; fillY++) {
this.walls[x][fillY] = true;
}
}
}
};
// Apply wall line completion after initial generation
worldGrid.completeWallLines();
// Create wall renderer
var wallRenderer = new WallRenderer();
game.addChild(wallRenderer);
wallRenderer.generateWalls();
// Create ceiling tile renderer
var ceilingTileRenderer = new CeilingTileRenderer();
game.addChild(ceilingTileRenderer);
ceilingTileRenderer.generateTiles();
// Create player
var player = new Player();
// Position player at a valid starting location in the world grid
player.x = worldGrid.cellSize * 1.5; // Start in cell (1,1)
player.y = worldGrid.cellSize * 1.5;
game.addChild(player);
// Create 3D renderer
var renderer3D = new Renderer3D();
game.addChild(renderer3D);
// Create coordinate display text
var coordXText = new Text2('X: 0', {
size: 60,
fill: 0xFFFFFF
});
coordXText.anchor.set(0, 0);
coordXText.x = 120; // Avoid top-left 100x100 area
coordXText.y = 120;
LK.gui.addChild(coordXText);
var coordZText = new Text2('Z: 0', {
size: 60,
fill: 0xFFFFFF
});
coordZText.anchor.set(0, 0);
coordZText.x = 120; // Avoid top-left 100x100 area
coordZText.y = 200;
LK.gui.addChild(coordZText);
// Create settings button in top-right corner (larger for mobile)
var settingsButton = LK.getAsset('untexturedArea', {
anchorX: 1,
anchorY: 0,
width: 120,
height: 120
});
settingsButton.tint = 0x444444;
settingsButton.alpha = 0.7;
LK.gui.topRight.addChild(settingsButton);
var settingsText = new Text2('⚙', {
size: 60,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsText.x = -60;
settingsText.y = 60;
LK.gui.topRight.addChild(settingsText);
// Create sensitivity configuration panel
var sensitivityConfig = new SensitivityConfig();
sensitivityConfig.x = 2048 - 320;
sensitivityConfig.y = 100;
LK.gui.addChild(sensitivityConfig);
// Movement flags
var moveForward = false;
var moveBackward = false;
var turnLeft = false;
var turnRight = false;
// Touch controls for movement
var touchStartX = 0;
var touchStartY = 0;
var touchActive = false;
// Settings button click handler
settingsButton.down = function (x, y, obj) {
sensitivityConfig.toggle();
};
game.down = function (x, y, obj) {
touchStartX = x;
touchStartY = y;
touchActive = true;
// Forward movement on touch
moveForward = true;
};
game.up = function (x, y, obj) {
touchActive = false;
moveForward = false;
moveBackward = false;
turnLeft = false;
turnRight = false;
};
game.move = function (x, y, obj) {
if (!touchActive) return;
var deltaX = x - touchStartX;
var deltaY = y - touchStartY;
// Horizontal movement for turning
if (Math.abs(deltaX) > 50) {
if (deltaX > 0) {
turnRight = true;
turnLeft = false;
} else {
turnLeft = true;
turnRight = false;
}
} else {
turnLeft = false;
turnRight = false;
}
// Vertical movement for forward/backward
if (Math.abs(deltaY) > 50) {
if (deltaY < 0) {
moveForward = true;
moveBackward = false;
} else {
moveBackward = true;
moveForward = false;
}
}
};
game.update = function () {
// Update player rotation speed based on sensitivity (0-100 maps to 0.05-0.2)
var sensitivityValue = sensitivityConfig.sensitivity;
player.rotSpeed = 0.05 + sensitivityValue / 100 * 0.15;
// Handle movement
if (moveForward) {
player.moveForward();
}
if (moveBackward) {
player.moveBackward();
}
if (turnLeft) {
player.turnLeft();
}
if (turnRight) {
player.turnRight();
}
// Apply smooth interpolation
player.updateSmooth();
// Render the pseudo-3D view
renderer3D.render(player);
// Render walls
wallRenderer.render(player);
// Render ceiling tiles
ceilingTileRenderer.render(player);
// Update coordinate display
var gridX = Math.floor(player.x / worldGrid.cellSize);
var gridZ = Math.floor(player.y / worldGrid.cellSize);
coordXText.setText('X: ' + gridX);
coordZText.setText('Z: ' + gridZ);
}; ===================================================================
--- original.js
+++ change.js
@@ -286,9 +286,9 @@
// Mold square texture to fit coordinate-based dimensions
self.wallColumns[i].height = wallHeight;
self.wallColumns[i].width = wallWidth;
self.wallColumns[i].y = wallBottom; // Anchor at bottom of wall
- self.wallColumns[i].visible = true;
+ self.wallColumns[i].visible = false; // Remove wall texture
// Apply texture coordinate molding based on hit position
var gridX = Math.floor(hitX / worldGrid.cellSize);
var gridY = Math.floor(hitY / worldGrid.cellSize);
// Calculate texture offset within the grid cell for seamless tiling
@@ -604,9 +604,9 @@
wall.sprite.x = wall.moldSprite.x;
wall.sprite.y = wall.moldSprite.y;
wall.sprite.width = wall.moldSprite.width;
wall.sprite.height = wall.moldSprite.height;
- wall.sprite.visible = true;
+ wall.sprite.visible = false; // Remove wall texture
wall.lastVisible = true;
// Force texture alignment to coordinate boundaries
// Calculate texture offset based on exact grid position
var textureOffsetX = wall.gridX % 2 * 0.5;
@@ -627,9 +627,9 @@
wall.sprite.stripe.x = screenX;
wall.sprite.stripe.y = screenY - wallHeight * 0.3;
wall.sprite.stripe.width = wallWidth;
wall.sprite.stripe.height = Math.max(4, wallHeight * 0.1);
- wall.sprite.stripe.visible = true;
+ wall.sprite.stripe.visible = false; // Remove wall stripe texture
wall.sprite.stripe.alpha = alpha * 0.8;
}
};
return self;