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 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
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 { 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}`,
|
||||
|
|
17
src/main.ts
17
src/main.ts
|
@ -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) => {
|
||||
|
|
18
src/utils.ts
18
src/utils.ts
|
@ -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 })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue