Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Phone explore WIP #21

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

Stuff

- mobile exploration:

- gameplay can actually be ok on iOS?
- canvas fill fix
- redo the menu for touch :-(
- test on smaller ios + ipad
- check this page: https://medium.com/appscope/designing-native-like-progressive-web-apps-for-ios-1b3cdda1d0e8

- sharing idea: shareable stats page powered with some persistence / random playerid
- bowling beast 8-ball character
- more characters?
Expand Down
6 changes: 0 additions & 6 deletions dist/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ body.in-game #game-canvas-wrapper {
display: block;
}

.phone-warning {
font-size: 20px;
text-align: center;
padding: 20px;
}

/* General Site Style sTuff */
.navbar-brand,
.navbar-brand:hover,
Expand Down
9 changes: 0 additions & 9 deletions src/backend/views/game.toffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,6 @@

<div id="game-load-wrapper">

<!-- only visible on smaller viewports-->
<div style="display:none;" class="phone-warning">
⚠️<br>
<b>Tippy Coco</b> is for computers, not phones or tablets. An <b>iPad</b> works with one of
those folding keyboards, but that's it. It will not play on phones.
</p>
</div>


<div class="intro-note">
<div style="text-align:center">
<img src="/images/site/cover.png" class="img-fluid">
Expand Down
4 changes: 2 additions & 2 deletions src/backend/views/site-header.toffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
<head>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" type="text/css" href="./index.css">
<title>Tippy Coco</title>
</head>
<body>
<body style="touch-action: none;">
{#
if includeGame {:
<div class="world-container">
Expand Down
11 changes: 1 addition & 10 deletions src/frontend/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,8 @@ class Display {
this.drawPlayerShadowBehind(playerRight)

this.drawKapows(kapowManager)

for (const player of [this.game.playerLeft, this.game.playerRight]) {
let closestBall = this.game.balls[0]
let closestDistance = Infinity
for (const ball of this.game.balls) {
const distance = vec.lenSq(vec.sub(ball.physics.center, player.physics.center))
if (distance < closestDistance) {
closestDistance = distance
closestBall = ball
}
}
const closestBall = this.game.getClosestBall(player.physics.center)
this.drawPlayer(gameTime, player, closestBall)
}
this.game.balls.forEach((b) => this.drawBall(b))
Expand Down
31 changes: 29 additions & 2 deletions src/frontend/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -416,19 +416,33 @@ class Game {
const player = this.player(playerSide)

if (player.species === PlayerSpecies.Human) {
player.targetXVel = player.isDashing ? player.physics.vel.x : 0
if (this.input.isPlayingWithTouch) {
if (player.isInJumpPosition) player.targetXVel = 0
else player.targetXVel = player.physics.vel.x
} else {
player.targetXVel = player.isDashing ? player.physics.vel.x : 0
}
// the following is -1...1 and maps to 0 if near the center, as determined
// in tweakables.thumbstickCenterTolerance
const thumbstickPos = this.input.getLeftThumbStickX(playerSide)
const touchMoveX = this.input.getTouchThumbstickX()
if (!player.isDashing) {
if (this.input.isLeftPressed(playerSide)) player.moveLeft()
else if (this.input.isRightPressed(playerSide)) player.moveRight()
else if (thumbstickPos) player.moveRationally(thumbstickPos)
else if (touchMoveX) player.moveRationally(touchMoveX)
if (player.canDashNow && this.input.wasDashJustPushed(playerSide)) {
const dashDir = this.getDashDir(player)
player.dash(dashDir)
this.sound.play('dash', 1, 0, 0, false)
} else if (player.isInJumpPosition && this.input.isJumpPressed(playerSide)) player.jump()
} else if (player.isInJumpPosition) {
if (this.input.isJumpPressed(playerSide)) player.jump()
else if (this.input.didJumpViaTouch()) {
const b = this.getClosestBall(player.physics.center)
const dir = vec.normalized(vec.sub(b.physics.center, player.physics.center))
player.jumpTowards(dir)
}
}
}
// triggers only register over some threshold as dtermined in tweakables.triggerTolerance
const lTrigger = this.input.getTrigger(playerSide, 'left')
Expand Down Expand Up @@ -609,6 +623,19 @@ class Game {
}
}

public getClosestBall(p: Vector2): Ball {
let closestBall = this.balls[0]
let closestDSq = Infinity
for (const ball of this.balls) {
const dSq = vec.lenSq(vec.sub(ball.physics.center, p))
if (dSq < closestDSq) {
closestDSq = dSq
closestBall = ball
}
}
return closestBall
}

// keeps balls within the flowers; this is a simple/fast solution
// to the problem of a multi-object pileup that could otherwise push them through.
// Also, if we were to allow a y-velocity so high they could go over the flowers,
Expand Down
35 changes: 32 additions & 3 deletions src/frontend/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,29 @@ import {GamepadConnectSummary, GamepadMonitor, TriggerName} from './gamepad-moni
import {KeyboardMonitor} from './keyboard-monitor'
import {MenuOwnership} from './menu'
import {PlayerSpecies} from './player'
import {ScreenSide, TouchDeviceMonitor, TouchMoveDelta} from './touch-device-monitor'
import tweakables from './tweakables'
import {MenuSelectResult, PlayerSide, Vector2} from './types'
import {vec} from './utils'

class Input {
private pads = new GamepadMonitor()
private keyboard = new KeyboardMonitor()
private touch = new TouchDeviceMonitor()
private game: Game
private _isPlayingWithTouch = false

public constructor(game: Game) {
this.game = game
}
public updateInputStates(): void {
this.keyboard.update()
this.pads.update()
this.touch.update()
}
public get isPlayingWithTouch() {
return this._isPlayingWithTouch
}

public isKeyboardConnected(): boolean {
return true // for now
}
Expand Down Expand Up @@ -47,7 +54,10 @@ class Input {
byPlayerSide: null,
byKeyboard: false,
}
if (this.keyboard.anyKeysJustPushed(['Enter', 'Space'])) {
if (this.touch.wasScreenJustTapped()) {
res.selected = true
res.byKeyboard = true
} else if (this.keyboard.anyKeysJustPushed(['Enter', 'Space'])) {
res.selected = true
res.byKeyboard = true
} else {
Expand Down Expand Up @@ -121,11 +131,30 @@ class Input {
const set = this.getKeyboardSet(pI)
return this.keyboard.anyKeyDown(set.dash) || this.pads.anyButtonDown(pI, ['psSquare'])
}

public isJumpPressed(pI: PlayerSide): boolean {
const set = this.getKeyboardSet(pI)
return this.keyboard.anyKeyDown(set.jump) || this.pads.anyButtonDown(pI, ['psX'])
}
public didJumpViaTouch(): boolean {
const res = !!this.touch.anyTap(ScreenSide.Right)
this._isPlayingWithTouch ||= res
return res
}
public getTouchThumbstickX(): number {
const t = this.touch.anyDragMovement(ScreenSide.Left)
if (!t) return 0
else {
this._isPlayingWithTouch = true
const x = t.vAsScreenFrac.x * tweakables.touch.xMoveMult
return Math.max(-1, Math.min(1, x))
}
}
/*
public isPulledBackTouch(): TouchMoveDelta | false {
const res = this.touch.isPulledBack()
if (res) this._isPlayingWithTouch = true
return res
}*/
/**
* returns 0 if trigger near 0, within tolerance
* defined in tweakables. otherwise returns value up to 1
Expand Down
12 changes: 10 additions & 2 deletions src/frontend/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,17 @@ class Player {
}
return false
}

public jumpTowards(dir: Vector2): boolean {
if (this.isInJumpPosition) {
this._jumpCount++
this.physics.vel.y = this.jumpSpeed * dir.y
this.physics.vel.x = this.jumpSpeed * dir.x
return true
}
return false
}
public dash(dir: Vector2) {
console.log('player::dash', this._isDashing)
console.log('player::dash', this._isDashing, 'can dash=', this.canDashNow)
if (this.canDashNow) {
this._isDashing = true
this.physics.density = 234
Expand Down
6 changes: 5 additions & 1 deletion src/frontend/site/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ class Site {
await timeout(250) // all we are saying...is give paint a chance
console.log('running. isMobileDevice=', isMobile())
if ($('#game-canvas-wrapper')) {
if (isMobile()) $('.phone-warning').style.display = ''
this.loadGame()
}
}
private addHandlers() {
const btnEraseStorage = $('#btn-erase-storage')
btnEraseStorage?.addEventListener('click', () => this.eraseLocalStorage())
window.addEventListener('keydown', (e: KeyboardEvent) => this.keyDown(e))
window.addEventListener('touchend', (e: TouchEvent) => this.endTouch(e))
}
private eraseLocalStorage() {
if (confirm('Are you sure? This will clear your game stats.')) {
Expand Down Expand Up @@ -50,5 +50,9 @@ class Site {
private keyDown(e: KeyboardEvent) {
if (e.key === ' ') this.launchGame()
}
private endTouch(e: TouchEvent) {
console.log(e)
this.launchGame()
}
}
export {Site}
Loading