Skip to content

Commit

Permalink
wip: add basic water physics logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Stan-Stani committed Jan 11, 2024
1 parent 8dcfe21 commit 81d27ce
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 51 deletions.
3 changes: 3 additions & 0 deletions src/debugging/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export function stickyMessage(...messages: any) {

identifier = getStackIdentifier()
for (const message of messages) {
if (message === undefined || message === null) {
throw new Error('Current message is ' + message)
}
if (message.hasOwnProperty('_id')) {
identifier = message._id
continue
Expand Down
144 changes: 93 additions & 51 deletions src/games/bobber.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { GameObjects, Scene } from 'phaser'
import { clearStickyMessage, stickyMessage, toastMessage } from '../debugging/tools'
import {
clearStickyMessage,
stickyMessage,
toastMessage,
} from '../debugging/tools'
const WIDTH = 256
const HEIGHT = 240
const GRAVITY = 128
Expand All @@ -14,7 +18,7 @@ interface IPlayer extends Phaser.Types.Physics.Arcade.SpriteWithDynamicBody {
right: boolean
left: boolean
}
waterCollider: Phaser.Types.Physics.Arcade.ImageWithDynamicBody
isImmersed: boolean
}

export class BobberScene extends Scene {
Expand Down Expand Up @@ -72,6 +76,46 @@ export class BobberScene extends Scene {
}
}

getTileAtBottomOfSprite(
sprite: Phaser.Types.Physics.Arcade.SpriteWithDynamicBody,
tileLayer: Phaser.Tilemaps.TilemapLayer,
tileIndex?: number
): Phaser.Tilemaps.Tile | null {
let tile: Phaser.Tilemaps.Tile | null = tileLayer.getTileAtWorldXY(
sprite.body.x + sprite.body.halfWidth,
sprite.body.y + sprite.body.height
)
if (tile) {
if (tileIndex && tileIndex === tile?.index) {
return tile
} else if (!tileIndex) {
return tile
}
}
return null
}

calculateVerticalOverlap(
sprite: Phaser.Types.Physics.Arcade.SpriteWithDynamicBody,
tile: Phaser.Tilemaps.Tile
) {
let spriteBounds = sprite.getBounds()
let tileBounds = tile.getBounds()

// Determine the overlapping rectangle
let intersection = Phaser.Geom.Rectangle.Intersection(
spriteBounds,
tileBounds as Phaser.Geom.Rectangle
)

// Calculate the percentage of overlap
let overlapHeight = intersection.height
let spriteHeight = spriteBounds.height
let overlapPercentage = (overlapHeight / spriteHeight) * 100

return overlapPercentage
}

preload() {
this.load.image('player', './bobber/player.png')
this.load.image('enemy', './enemy.png')
Expand All @@ -82,7 +126,6 @@ export class BobberScene extends Scene {
create() {
this.physics.world.setBounds(0, 0, WIDTH * 11, HEIGHT)
this.cameras.main.setBounds(0, 0, 1024 * 4, HEIGHT)


const map = this.make.tilemap({ key: 'tilemapLevel1' })
const tileset = map.addTilesetImage('tiles', 'tiles')
Expand Down Expand Up @@ -119,7 +162,7 @@ export class BobberScene extends Scene {

this.#playerOne = this.physics.add.sprite(
this.#spawnPlayer[0].x,
this.#spawnPlayer[0].y -50,
this.#spawnPlayer[0].y - 50,
'player'
) as IPlayer
this.#playerOne?.body
Expand All @@ -129,18 +172,9 @@ export class BobberScene extends Scene {
directionBeforeBraking: undefined,
}
this.#playerOne.keyInfo = { left: false, right: false }

// this.#playerOne.waterCollider = this.physics.add.image(this.#spawnPlayer[0].x, this.#spawnPlayer[0].y, 'player')
// // this.#playerOne.waterCollider.setVisible(false)
// this.#playerOne.waterCollider.body.setSize(this.#playerOne.body.width, this.#playerOne.body.height * (2/3), false)
// this.#playerOne.waterCollider.body.setAllowGravity(false)

// this.#playerOne.waterCollider.debugBodyColor = 0x00ff00
// this.#playerOne.setCollideWorldBounds(true, 0.1, 0.1, true)

// this.#playerOne.setBounce(0.1, 0.1)

this.#playerOne.setDamping(true)
this.#playerOne.isImmersed = false

this.cameras.main.startFollow(this.#playerOne, true)
// this.cameras.main.setDeadzone(400, 200);

Expand Down Expand Up @@ -317,23 +351,6 @@ export class BobberScene extends Scene {
})
}

// if (this.#water) {
// stickyMessage(this.#playerOne)
// stickyMessage(this.#water)
// const collider = this.physics.add.collider(
// this.#playerOne,
// this.#water,
// (thing) => {
// console.log('water collided')
// // this.#playerOne?.body.setAllowGravity(false)
// },
// (ob1, ob2) => {
// console.log(ob1, ob2)
// }
// )

// }

// if (this.#water) {
// stickyMessage(this.#playerOne)
// stickyMessage(this.#water)
Expand All @@ -348,10 +365,8 @@ export class BobberScene extends Scene {
// console.count('lol')
// }
// )

// }


// }

// Listen for the 'worldbounds' event

Expand All @@ -366,6 +381,10 @@ export class BobberScene extends Scene {
}

update(_time: number, delta: number) {
stickyMessage(
'playerOne Net Gravity:',
(this.#playerOne?.body.gravity.y ?? 0) + GRAVITY
)
stickyMessage('playerOne Velocity:', this.#playerOne?.body?.velocity)
stickyMessage(
'playerOne Acceleration:',
Expand All @@ -374,11 +393,6 @@ export class BobberScene extends Scene {
stickyMessage('brakingInfo:', this.#playerOne?.brakingInfo)
if (!this.#playerOne) return

// stickyMessage(this.#playerOne.waterCollider.body.x)
// this.#playerOne.waterCollider.body.x = this.#playerOne.body.x
// this.#playerOne.waterCollider.body.y = this.#playerOne.body.y


// Don't waste time calculating super small velocity endlessly for drag
if (
Math.abs(this.#playerOne?.body?.velocity.x ?? 0) < 0.1 &&
Expand Down Expand Up @@ -411,16 +425,11 @@ export class BobberScene extends Scene {
}
}



// @ts-ignore
// stickyMessage(this.#playerOne?.body?.drag)

// stickyMessage(this.#playerOne?.body?.velocity)

const friction = 0.35 // friction coefficient
const deltaInSeconds = delta / 1000 // Convert delta to seconds

// Apply friction factor to the player's velocity and make it frame rate independent

if (this.#playerOne?.body) {
Expand All @@ -433,14 +442,47 @@ export class BobberScene extends Scene {
// }
// }

const tile = this.#water?.getTileAtWorldXY(this.#playerOne.body.x + this.#playerOne.body.width / 2, this.#playerOne.body.y + this.#playerOne.body.height)
let isInWater = false
console.log(tile?.index)
const tile = this.#water?.getTileAtWorldXY(
this.#playerOne.body.x + this.#playerOne.body.width / 2,
this.#playerOne.body.y + this.#playerOne.body.height / 3
)
this.#playerOne.isImmersed = false
if (tile?.index === 17 || tile?.index === 33) {
isInWater = true

this.#playerOne.isImmersed = true
}
stickyMessage({ isImmersed: this.#playerOne.isImmersed })

if (this.#playerOne.isImmersed) {
this.#playerOne.setGravityY(-2 * GRAVITY)
} else {
this.#playerOne.setGravityY(0)
}


if (this.#water) {
// If we're passing through the top layer of water
const tile = this.getTileAtBottomOfSprite(
this.#playerOne,
this.#water,
17
)
stickyMessage(tile?.index + ' hey ')

if (tile) {
const percentOverlap = this.calculateVerticalOverlap(
this.#playerOne,
tile
)

this.#playerOne.setGravityY(-GRAVITY * (percentOverlap / 100))

stickyMessage(percentOverlap)
} else if (this.#playerOne.isImmersed) {
this.#playerOne.setGravityY(-2 * GRAVITY)
}


}
stickyMessage({isInWater})

if (!this.#playerOne.body.blocked.down) {
this.#playerOne?.setDrag(0.75, 0)
Expand Down

0 comments on commit 81d27ce

Please sign in to comment.