Soporte mobile

This commit is contained in:
Nulo 2021-07-01 22:33:51 +00:00
parent 6a650203f9
commit c7b766dec6
6 changed files with 118 additions and 13 deletions

View file

@ -1,4 +1,5 @@
import botonJugarImg from "./assets/boton_jugar.png";
import flechaImg from "./assets/flecha.png";
import larretaImg from "./assets/Larreta.png";
import millonarioMaloPng from "./assets/Millonario Malo.png";
import cieloRioCalleImg from "./assets/CieloRioCalle.png";
@ -24,6 +25,7 @@ function loadImage(url: string): Promise<HTMLImageElement> {
export const assetUrls = {
botonJugar: botonJugarImg,
flecha: flechaImg,
larreta: larretaImg,
millonarioMalo: millonarioMaloPng,
cieloRioCalle: cieloRioCalleImg,

BIN
src/assets/flecha.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

View file

@ -1,6 +1,14 @@
import { Juego } from "./main";
import { Sprite } from "./sprite";
import { Box, boxCollision, drawText, randomFromArray } from "./utils";
import {
Box,
boxCollision,
drawText,
isMobile,
isTouching,
posInBox,
randomFromArray,
} from "./utils";
const ENEMIES_NUM = 12;
const SEED_COOLDOWN = 300;
@ -37,6 +45,33 @@ export function createJugandoState(): State {
};
}
function touchControls(juego: Juego<State>): {
left: Box;
right: Box;
center: Box;
} {
return {
left: {
x: 0,
y: 0,
width: juego.canvas.width / 7,
height: juego.canvas.height,
},
right: {
x: juego.canvas.width - juego.canvas.width / 7,
y: 0,
width: juego.canvas.width / 7,
height: juego.canvas.height,
},
center: {
x: juego.canvas.width / 7,
y: 0,
width: juego.canvas.width - (juego.canvas.width / 7) * 2,
height: juego.canvas.height,
},
};
}
export function update(juego: Juego<State>, dt: number) {
juego.state.time -= dt;
if (juego.state.time < 0) {
@ -46,11 +81,20 @@ export function update(juego: Juego<State>, dt: number) {
const playerSpeed = juego.canvas.width * 0.15;
const enemySpeed = juego.canvas.width * 0.05;
if (juego.keyboard.keys.d || juego.keyboard.keys.ArrowRight) {
const { left, right, center } = touchControls(juego);
if (
juego.keyboard.keys.d ||
juego.keyboard.keys.ArrowRight ||
isTouching(juego, right)
) {
juego.state.side = "right";
juego.state.pos.x += (dt / 1000) * playerSpeed;
}
if (juego.keyboard.keys.a || juego.keyboard.keys.ArrowLeft) {
if (
juego.keyboard.keys.a ||
juego.keyboard.keys.ArrowLeft ||
isTouching(juego, left)
) {
juego.state.side = "left";
juego.state.pos.x -= (dt / 1000) * playerSpeed;
}
@ -59,7 +103,10 @@ export function update(juego: Juego<State>, dt: number) {
if (juego.state.pos.x > MAP_MAX) juego.state.pos.x = MAP_MAX;
juego.state.seedCooldown -= dt;
if (juego.keyboard.keys[" "] && juego.state.seedCooldown < 0) {
if (
(juego.keyboard.keys[" "] || isTouching(juego, center)) &&
juego.state.seedCooldown < 0
) {
const seedSpeed = juego.canvas.width * 0.7;
juego.state.seeds.push({
x: juego.state.pos.x,
@ -271,14 +318,32 @@ export function draw(juego: Juego<State>, timestamp: number) {
drawJugadorx(juego);
drawSeeds(juego);
juego.ctx.fillStyle = "white";
drawText(
juego,
'Usá las flechitas para moverte, y espacio para "disparar" semillas.',
{ x: 0, y: 100 },
{}
);
if (isMobile()) {
const { left, right } = touchControls(juego);
juego.ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
juego.ctx.fillRect(left.x, left.y, left.width, left.height);
juego.ctx.fillRect(right.x, right.y, right.width, right.height);
const width = juego.sprites.flecha.getWidth(juego);
const height = juego.sprites.flecha.getHeight(juego);
juego.sprites.flecha.draw(
juego,
left.x + left.width - width,
left.height / 2 - height / 2,
0,
false
);
juego.sprites.flecha.draw(
juego,
right.x,
right.height / 2 - height / 2,
0,
true
);
}
juego.ctx.fillStyle = "white";
const arbolesBox = drawText(
juego,
`Arboles: ${juego.state.trees.length}/${TREES_TO_WIN}`,

View file

@ -15,6 +15,7 @@ export type Juego<T extends State> = {
assets: Assets;
sprites: {
[key in
| "flecha"
| "jugadorx"
| "baldosa"
| "larreta"
@ -24,6 +25,7 @@ export type Juego<T extends State> = {
| "arbol2"]: Sprite;
};
mouse: { x: number; y: number; down: boolean };
touches: TouchList | null;
keyboard: { keys: { [key: string]: boolean } };
state: T;
};
@ -74,6 +76,10 @@ function resizeCanvas(canvas: HTMLCanvasElement) {
canvas.height = canvas.clientHeight;
}
function touchListener(juego: Juego<any>, event: TouchEvent) {
juego.touches = event.touches;
}
async function initJuego() {
const canvas = document.querySelector<HTMLCanvasElement>("#juego")!;
const ctx = canvas.getContext("2d", {
@ -87,6 +93,12 @@ async function initJuego() {
const assets = await loadAssets();
const sprites = {
flecha: loadSprite(
assets.flecha,
11,
9,
(juego) => juego.canvas.height / 6
),
jugadorx: loadSprite(
assets.jugadorx,
65,
@ -137,6 +149,7 @@ async function initJuego() {
assets,
sprites,
mouse: { x: 0, y: 0, down: false },
touches: null,
keyboard: { keys: {} },
state: {
current: "welcome",
@ -173,6 +186,10 @@ async function initJuego() {
window.addEventListener("keyup", (e) => {
juego.keyboard.keys[e.key] = false;
});
window.addEventListener("touchstart", (e) => touchListener(juego, e));
window.addEventListener("touchend", (e) => touchListener(juego, e));
window.addEventListener("touchcancel", (e) => touchListener(juego, e));
window.addEventListener("touchmove", (e) => touchListener(juego, e));
let lastRender = 0;
const loop: FrameRequestCallback = (timestamp) => {

View file

@ -60,3 +60,21 @@ export function drawText(
export function randomFromArray<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)];
}
export function isMobile(): boolean {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
export function isTouching(juego: Juego<any>, box: Box): boolean {
return !!(
juego.touches &&
Array.from(juego.touches).some((t) =>
posInBox(box, { x: t.pageX, y: t.pageY })
)
);
}

View file

@ -1,4 +1,4 @@
import { posInBox } from "./utils";
import { isTouching, posInBox } from "./utils";
import { createJugandoState } from "./jugando";
import { Juego } from "./main";
@ -21,7 +21,10 @@ function startButton(juego: Juego<State>) {
export function update(juego: Juego<State>, dt: number) {
const btn = startButton(juego);
if (juego.mouse.down && posInBox(btn, juego.mouse)) {
if (
(juego.mouse.down && posInBox(btn, juego.mouse)) ||
isTouching(juego, btn)
) {
(juego as Juego<any>).state = createJugandoState();
}
}