So, i’m almost done with my baba is you tilemap demo, but just as i was about to finish i encountered this issue. Take a look:
The boxes dissapear when i push them into the border! For clarity, baba also stops when you go into the border.
For this, i dont actually need code, i just need a general idea of how to fix this. This is the algorithm i have currently:
step 1: find what baba is trying to push
step 2: push that box
step 3: check if the box has a box in front of it
repeat step 3 and 2 until no boxes are in front of eachother anymore
important: there is a IsWallAt(location) function, that may help you
Code (feedback would be appreciated)
namespace spriteMap {
export const tileMapSizePix = 8
export const tilesXPerScreen = Math.floor(19 / (tileMapSizePix / 8))+1
export const tilesYPerScreen = Math.floor(14 / (tileMapSizePix / 8))+2
export const clearImage = img`
. c . . c c c .
c c c . . c . .
c . c . c c c .
. . . . . . . .
c c . . . . . .
c c c . . . . .
c . c . . . . .
. . . . . . . .
`//image.create(tileMapSizePix, tileMapSizePix)
//["tile", new tileLocation, img``]
export const allThings: { [key: string]: string } = {
//Entities
"baba": "baba",
//Tiles
"air": "air",
"wall": "wall",
"grass": "grass",
//Joiners
}
export class tileLocation {
tx = 0
ty = 0
constructor(tx: number, ty: number) {
this.tx = tx;
this.ty = ty;
}
}
export class tile {
tx = 0
ty = 0
id = "wall"
img = clearImage
xoff = 0
yoff = 0
moving = false
constructor(tx: number, ty: number, id: string, img: Image, xoff : number = 0, yoff : number = 0) {
this.tx = tx;
this.ty = ty;
this.id = id;
this.img = img;
this.xoff = xoff;
this.yoff = yoff;
console.log(spriteMap.allThings)
if (allThings[id]) {
this.id = id
} else {
this.id = "air"
}
console.log(this.id)
}
clone() {
return new tile(this.tx, this.tx, this.id, this.img)
}
}
export let currentTileMap = [
new spriteMap.tile(8, 8, "wall", clearImage)
]
currentTileMap = []
for (let y = 0; y < tilesYPerScreen; y++) {
for (let x = 0; x < tilesXPerScreen; x++) {
currentTileMap.push(new spriteMap.tile(x, y, "air", clearImage))
}
}
setTile(new spriteMap.tile(5, 5, "wall", img`
2 2 2 2 2 2 2 2
2 3 2 2 3 2 2 2
2 3 3 2 3 2 2 2
2 2 2 2 2 2 2 2
3 3 2 2 2 2 2 2
2 3 2 2 3 2 2 2
2 3 3 3 3 2 2 2
2 2 2 2 2 2 2 2
`))
setTile(new spriteMap.tile(6, 5, "wall", img`
2 2 2 2 2 2 2 2
2 3 2 2 3 2 2 2
2 3 3 2 3 2 2 2
2 2 2 2 2 2 2 2
3 3 2 2 2 2 2 2
2 3 2 2 3 2 2 2
2 3 3 3 3 2 2 2
2 2 2 2 2 2 2 2
`))
setTile(new spriteMap.tile(7, 5, "wall", img`
2 2 2 2 2 2 2 2
2 3 2 2 3 2 2 2
2 3 3 2 3 2 2 2
2 2 2 2 2 2 2 2
3 3 2 2 2 2 2 2
2 3 2 2 3 2 2 2
2 3 3 3 3 2 2 2
2 2 2 2 2 2 2 2
`))
export function getTileAt(tileLocation : spriteMap.tileLocation) {
let x = Math.clamp(1, tilesXPerScreen, tileLocation.tx)
let y = Math.clamp(1, tilesYPerScreen, tileLocation.ty)
let tile = currentTileMap[x + (y * tilesXPerScreen)]
return tile
}
export function updateGraphics() {
}
export function setTile(tile: spriteMap.tile) {
let x = tile.tx//Math.clamp(1, tilesXPerScreen, tile.tx)
let y = tile.ty//Math.clamp(1, tilesYPerScreen, tile.ty)
currentTileMap[x + (y * tilesXPerScreen)] = tile
}
export function isWallAt(tileLocation : spriteMap.tileLocation) {
let wall = false
if (tileLocation.tx < 1 || tileLocation.ty < 1) {
wall = true
}
if (tileLocation.tx > tilesXPerScreen-2 || tileLocation.ty > tilesYPerScreen-2) {
wall = true
}
if (getTileAt(tileLocation).id != "air") {
wall = true
}
return wall
}
export function isBorderAt(tileLocation: spriteMap.tileLocation) {
let wall = false
if (tileLocation.tx < 1 || tileLocation.ty < 1) {
wall = true
}
if (tileLocation.tx > tilesXPerScreen - 2 || tileLocation.ty > tilesYPerScreen - 2) {
wall = true
}
return wall
}
export function moveToTile(sprite: Sprite, tileLocation : spriteMap.tileLocation) {
if (sprite.data["moving"] == true) {
return false
}
let tileloc = tileLocation//new spriteMap.tileLocation(Math.clamp(1, tilesXPerScreen-1, tileLocation.tx), Math.clamp(1, tilesYPerScreen-2, tileLocation.ty))
if (isWallAt(tileLocation) == true) {
return false
}
sprite.data["moving"] = true
for (let i = 0; i < tileMapSizePix; i++) {
pause(10)
let x = utilities.lerp(sprite.x, tileloc.tx * tileMapSizePix, i / tileMapSizePix)
let y = utilities.lerp(sprite.y, tileloc.ty * tileMapSizePix, i / tileMapSizePix)
sprite.x = x
sprite.y = y
}
sprite.x = tileloc.tx*tileMapSizePix
sprite.y = tileloc.ty*tileMapSizePix
sprite.data["moving"] = false
return !isWallAt(tileLocation)
}
export function stepTile(tile: spriteMap.tileLocation, x: number, y: number, i: number = 0) {
let movingTile = getTileAt(tile)
if (movingTile.moving == true) {
return false
}
if (isBorderAt(new spriteMap.tileLocation(tile.tx + x, tile.ty + y))) {
return false
}
if (isWallAt(new spriteMap.tileLocation(tile.tx + x, tile.ty + y))) {
//timer.after(10, function() {
//let temp = (0 == 1)//simulateStepTile(new spriteMap.tileLocation(tile.tx + x, tile.ty + y), x, y)
if (true) {
i+=1
stepTile(new spriteMap.tileLocation(tile.tx + x, tile.ty + y), x, y, i)
} else {
return false
}
// })
}
setTile(new spriteMap.tile(tile.tx, tile.ty, "air", clearImage))
let offx = x * tileMapSizePix * -1
let offy = y * tileMapSizePix * -1
let tile2 = new spriteMap.tile(tile.tx + x, tile.ty + y, movingTile.id, movingTile.img, offx, offy)
tile2.moving = true
setTile(tile2)
timer.background(function() {
for (let i = 0; i < tileMapSizePix; i++) {
pause(10)
let x = utilities.lerp(offx, 0, i / tileMapSizePix)
let y = utilities.lerp(offy, 0, i / tileMapSizePix)
tile2.xoff = x
tile2.yoff = y
}
tile2.xoff = 0
tile2.yoff = 0
tile2.moving = false
})
return true
}
export function step(sprite: Sprite, x : number, y : number) {
let loc = getSpritesTile(sprite)
loc.tx += x
loc.ty += y
if (isWallAt(loc) && getTileAt(loc).id != "air") {
//let tile = getTileAt(loc)
timer.background(function() {
stepTile(loc, x, y)
})
//let curloc = getSpritesTile(sprite)
//setTile(new spriteMap.tile(loc.tx,loc.ty,"air", clearImage))
//setTile(new spriteMap.tile(loc.tx + x, loc.ty + y, tile.id, tile.img))
//moveToTile(sprite, loc)
return false
} else {
moveToTile(sprite, loc)
return true
}
}
export function getSpritesTile(sprite : Sprite) {
let x = Math.floor(sprite.x/tileMapSizePix)
let y = Math.floor(sprite.y / tileMapSizePix)
return new tileLocation(x,y)
}
scene.createRenderable(0, function () {
for (let i = 0; i < currentTileMap.length; i++) {
let tile = currentTileMap[i]
let img1 = tile.img
let x = (tile.tx-1) * tileMapSizePix + (tileMapSizePix / 2)
let y = (tile.ty-1) * tileMapSizePix + (tileMapSizePix/2)
image.screenImage().drawTransparentImage(img1, x+tile.xoff, y+tile.yoff)
}
})
}