Soporte mobile
This commit is contained in:
parent
6a650203f9
commit
c7b766dec6
6 changed files with 118 additions and 13 deletions
|
@ -1,4 +1,5 @@
|
||||||
import botonJugarImg from "./assets/boton_jugar.png";
|
import botonJugarImg from "./assets/boton_jugar.png";
|
||||||
|
import flechaImg from "./assets/flecha.png";
|
||||||
import larretaImg from "./assets/Larreta.png";
|
import larretaImg from "./assets/Larreta.png";
|
||||||
import millonarioMaloPng from "./assets/Millonario Malo.png";
|
import millonarioMaloPng from "./assets/Millonario Malo.png";
|
||||||
import cieloRioCalleImg from "./assets/CieloRioCalle.png";
|
import cieloRioCalleImg from "./assets/CieloRioCalle.png";
|
||||||
|
@ -24,6 +25,7 @@ function loadImage(url: string): Promise<HTMLImageElement> {
|
||||||
|
|
||||||
export const assetUrls = {
|
export const assetUrls = {
|
||||||
botonJugar: botonJugarImg,
|
botonJugar: botonJugarImg,
|
||||||
|
flecha: flechaImg,
|
||||||
larreta: larretaImg,
|
larreta: larretaImg,
|
||||||
millonarioMalo: millonarioMaloPng,
|
millonarioMalo: millonarioMaloPng,
|
||||||
cieloRioCalle: cieloRioCalleImg,
|
cieloRioCalle: cieloRioCalleImg,
|
||||||
|
|
BIN
src/assets/flecha.png
Normal file
BIN
src/assets/flecha.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 604 B |
|
@ -1,6 +1,14 @@
|
||||||
import { Juego } from "./main";
|
import { Juego } from "./main";
|
||||||
import { Sprite } from "./sprite";
|
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 ENEMIES_NUM = 12;
|
||||||
const SEED_COOLDOWN = 300;
|
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) {
|
export function update(juego: Juego<State>, dt: number) {
|
||||||
juego.state.time -= dt;
|
juego.state.time -= dt;
|
||||||
if (juego.state.time < 0) {
|
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 playerSpeed = juego.canvas.width * 0.15;
|
||||||
const enemySpeed = juego.canvas.width * 0.05;
|
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.side = "right";
|
||||||
juego.state.pos.x += (dt / 1000) * playerSpeed;
|
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.side = "left";
|
||||||
juego.state.pos.x -= (dt / 1000) * playerSpeed;
|
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;
|
if (juego.state.pos.x > MAP_MAX) juego.state.pos.x = MAP_MAX;
|
||||||
|
|
||||||
juego.state.seedCooldown -= dt;
|
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;
|
const seedSpeed = juego.canvas.width * 0.7;
|
||||||
juego.state.seeds.push({
|
juego.state.seeds.push({
|
||||||
x: juego.state.pos.x,
|
x: juego.state.pos.x,
|
||||||
|
@ -271,14 +318,32 @@ export function draw(juego: Juego<State>, timestamp: number) {
|
||||||
drawJugadorx(juego);
|
drawJugadorx(juego);
|
||||||
drawSeeds(juego);
|
drawSeeds(juego);
|
||||||
|
|
||||||
juego.ctx.fillStyle = "white";
|
if (isMobile()) {
|
||||||
drawText(
|
const { left, right } = touchControls(juego);
|
||||||
juego,
|
|
||||||
'Usá las flechitas para moverte, y espacio para "disparar" semillas.',
|
|
||||||
{ x: 0, y: 100 },
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
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(
|
const arbolesBox = drawText(
|
||||||
juego,
|
juego,
|
||||||
`Arboles: ${juego.state.trees.length}/${TREES_TO_WIN}`,
|
`Arboles: ${juego.state.trees.length}/${TREES_TO_WIN}`,
|
||||||
|
|
17
src/main.ts
17
src/main.ts
|
@ -15,6 +15,7 @@ export type Juego<T extends State> = {
|
||||||
assets: Assets;
|
assets: Assets;
|
||||||
sprites: {
|
sprites: {
|
||||||
[key in
|
[key in
|
||||||
|
| "flecha"
|
||||||
| "jugadorx"
|
| "jugadorx"
|
||||||
| "baldosa"
|
| "baldosa"
|
||||||
| "larreta"
|
| "larreta"
|
||||||
|
@ -24,6 +25,7 @@ export type Juego<T extends State> = {
|
||||||
| "arbol2"]: Sprite;
|
| "arbol2"]: Sprite;
|
||||||
};
|
};
|
||||||
mouse: { x: number; y: number; down: boolean };
|
mouse: { x: number; y: number; down: boolean };
|
||||||
|
touches: TouchList | null;
|
||||||
keyboard: { keys: { [key: string]: boolean } };
|
keyboard: { keys: { [key: string]: boolean } };
|
||||||
state: T;
|
state: T;
|
||||||
};
|
};
|
||||||
|
@ -74,6 +76,10 @@ function resizeCanvas(canvas: HTMLCanvasElement) {
|
||||||
canvas.height = canvas.clientHeight;
|
canvas.height = canvas.clientHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function touchListener(juego: Juego<any>, event: TouchEvent) {
|
||||||
|
juego.touches = event.touches;
|
||||||
|
}
|
||||||
|
|
||||||
async function initJuego() {
|
async function initJuego() {
|
||||||
const canvas = document.querySelector<HTMLCanvasElement>("#juego")!;
|
const canvas = document.querySelector<HTMLCanvasElement>("#juego")!;
|
||||||
const ctx = canvas.getContext("2d", {
|
const ctx = canvas.getContext("2d", {
|
||||||
|
@ -87,6 +93,12 @@ async function initJuego() {
|
||||||
const assets = await loadAssets();
|
const assets = await loadAssets();
|
||||||
|
|
||||||
const sprites = {
|
const sprites = {
|
||||||
|
flecha: loadSprite(
|
||||||
|
assets.flecha,
|
||||||
|
11,
|
||||||
|
9,
|
||||||
|
(juego) => juego.canvas.height / 6
|
||||||
|
),
|
||||||
jugadorx: loadSprite(
|
jugadorx: loadSprite(
|
||||||
assets.jugadorx,
|
assets.jugadorx,
|
||||||
65,
|
65,
|
||||||
|
@ -137,6 +149,7 @@ async function initJuego() {
|
||||||
assets,
|
assets,
|
||||||
sprites,
|
sprites,
|
||||||
mouse: { x: 0, y: 0, down: false },
|
mouse: { x: 0, y: 0, down: false },
|
||||||
|
touches: null,
|
||||||
keyboard: { keys: {} },
|
keyboard: { keys: {} },
|
||||||
state: {
|
state: {
|
||||||
current: "welcome",
|
current: "welcome",
|
||||||
|
@ -173,6 +186,10 @@ async function initJuego() {
|
||||||
window.addEventListener("keyup", (e) => {
|
window.addEventListener("keyup", (e) => {
|
||||||
juego.keyboard.keys[e.key] = false;
|
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;
|
let lastRender = 0;
|
||||||
const loop: FrameRequestCallback = (timestamp) => {
|
const loop: FrameRequestCallback = (timestamp) => {
|
||||||
|
|
18
src/utils.ts
18
src/utils.ts
|
@ -60,3 +60,21 @@ export function drawText(
|
||||||
export function randomFromArray<T>(array: T[]): T {
|
export function randomFromArray<T>(array: T[]): T {
|
||||||
return array[Math.floor(Math.random() * array.length)];
|
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 })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { posInBox } from "./utils";
|
import { isTouching, posInBox } from "./utils";
|
||||||
import { createJugandoState } from "./jugando";
|
import { createJugandoState } from "./jugando";
|
||||||
import { Juego } from "./main";
|
import { Juego } from "./main";
|
||||||
|
|
||||||
|
@ -21,7 +21,10 @@ function startButton(juego: Juego<State>) {
|
||||||
|
|
||||||
export function update(juego: Juego<State>, dt: number) {
|
export function update(juego: Juego<State>, dt: number) {
|
||||||
const btn = startButton(juego);
|
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();
|
(juego as Juego<any>).state = createJugandoState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue