Создание коллизий с использованием карты из массива - PullRequest
0 голосов
/ 30 апреля 2020

Итак, я делаю игру Mario. Уровень сделан с использованием карты из массива.

const map = 

     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,];

    const size = 128;

Я хочу сделать функцию, которая бы возвращала индекс блока, который находится под Марио. Я попытался написать

export function findBlockUnder(posX: number, posY: number) {
for (let index = 0; index < map.length; index++) {
  return map[index]}
}

, но это возвращает только первый номер массива. Если бы я заставил это работать, после того, как я получил бы число для findBlockUnder, я написал бы что-то вроде этого

const floorUnderMario = findBlockUnder(posX, posY)
  if (floorUnderMario = "0") {
    velocityY += deltaTime * 0.003;
  } else {
    velocityY = 0;
  }

На данный момент я сделал 4 внешние границы, просто используя записанные координаты Y

export function findBlockUnder(posX: number, posY: number) {
  return 1320
}


export function findBlockAbove(posX: number, posY: number) {
  return 1200
}

export function findBlockRight(posX:number, posY:number){
  return 3380
}

export function findBlockLeft(posX:number, posY:number){
  return -375
}

const bloksPaLabi = findBlockRight(posX, posY);
  if (posX>bloksPaLabi){
    posX=bloksPaLabi;
  }

  const bloksPaKreisi = findBlockLeft(posX, posY);
  if (posX<bloksPaKreisi){
    posX=bloksPaKreisi;
  }

Итак, если бы кто-то мог мне помочь, как бы я написал код, чтобы получить индекс блока в разделе Марио? Вот полный код: level.ts

import bricksSrc from "./images/bricks3.png"
import questionSrc from "./images/question.png"

const siena = document.createElement("img");
siena.src = bricksSrc;

const question = document.createElement("img");
question.src = questionSrc;

const map = 
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,];

const size = 128;



export function findBlockUnder(posX: number, posY: number) {
  return 1320
}


export function findBlockAbove(posX: number, posY: number) {
  return 1200
}

export function findBlockRight(posX:number, posY:number){
  return 3380
}

export function findBlockLeft(posX:number, posY:number){
  return -375
}

export function MapDraw(context: CanvasRenderingContext2D, marioPosX: number, marioPosY: number) {

  const mapOffsetX = marioPosX;
  const mapOffsetY = marioPosY;


  for (let index = 0; index < map.length; index++) {
    const x = (index % 32);
    const y = Math.floor(index / 32);

    if (map[index] == 1) {
      context.drawImage(siena,
        x * size - mapOffsetX,
        y * size - mapOffsetY,
        size,
        size);
    }



    if (map[index] == 2) {
      context.drawImage(question,
        x * size - mapOffsetX,
        y * size - mapOffsetY,
        size,
        size);
    }




    // if (map[index] == 0) {
    //   context.fillStyle = "#ffffff"
    //   context.fillRect(x * size - mapOffsetX, y * size, size, size);
    // }
  }

  function resize() {
    let width = document.documentElement.clientWidth;
    let maxWidth = Math.floor(document.documentElement.clientHeight / 0.5625);
    if (width > maxWidth) {
      width = maxWidth;
    }
    context.canvas.style.width = width + "px";
    context.canvas.style.height = Math.floor(width * 0.5625) + "px";
  };

  window.addEventListener("resize", resize, { passive: true });

  resize();

}

mario.ts

import marioSrc from "./images/8mario_burned.png";

/*
const canvas = document.createElement("canvas2");
document.body.appendChild(canvas);

canvas.style.outline = "1px solid black";
canvas.style.cursor = "none";

*/

const mario = new Image();
mario.src = marioSrc;

export function drawMario(
    context: CanvasRenderingContext2D,
    centerX: number,
    centerY: number,
) {
    context.drawImage(mario, centerX, centerY, 100, 100);
}

index.ts

import { drawMario } from "./mario"
import {
  MapDraw,
  findBlockUnder,
  findBlockAbove,
  findBlockRight,
  findBlockLeft,
} from "./level"

import backSrc from "./images/background.png";

const canvas = document.createElement("canvas");
document.body.appendChild(canvas);

canvas.style.outline = "1px solid black";
canvas.style.cursor = "none";

canvas.width = 2048;
canvas.height = 1024;

const context = canvas.getContext("2d");

context.fillStyle = "rgb(200,120,60)";





const back = new Image();
back.src = backSrc;

function drawback(
  context: CanvasRenderingContext2D,
  posX: number,
  posY: number,
) {
  context.drawImage(back, -posX / 10, -posY / 10, canvas.width * 1.5, canvas.height * 1.5);
}


window.requestAnimationFrame(renderLoop);

const sprite2 = document.createElement("img");
sprite2.src =
  "https://i.pinimg.com/originals/4b/91/1c/4b911c7d968feeaa993d24c93ddb821e.png";

let posX = 20;
let posY = 20;
let velocityY = 0;
let velocityX = 0;
let previousTime = 0;
let movementStarted = 0;
let wasMoving = false;

let keysPressed: string[] = [];


canvas.oncontextmenu = function (event) {
  event.preventDefault();
};

/** NB! `document`, nevis `canvas` */
document.addEventListener("keydown", function (e) {
  if (keysPressed.indexOf(e.key) === -1) {
    keysPressed.push(e.key);
  }
});


document.addEventListener("keyup", function (e) {
  let idx = keysPressed.indexOf(e.key);
  if (idx > -1) {
    keysPressed.splice(idx, 1);
  }
});

function renderLoop(time: number) {
  context.clearRect(0, 0, canvas.width, canvas.height);

  if (previousTime === 0) {
    previousTime = time;
  }

  const deltaTime = time - previousTime;
  previousTime = time;

  moveMario(deltaTime);
  drawback(context, posX, posY);
  MapDraw(context, posX, posY);
  drawMario(context, 500, 500);
  // drawSprite2(time, deltaTime);


  window.requestAnimationFrame(renderLoop);
}

function moveMario(deltaTime: number) {
  const isMoving = keysPressed.indexOf("ArrowRight") > -1;
  if (isMoving) {
    posX += deltaTime * 0.8;
  }

  const isMovingLeft = keysPressed.indexOf("ArrowLeft") > -1;
  if (isMovingLeft) {
    posX -= deltaTime * 0.8;

      }


  const gridaZemMario = findBlockUnder(posX, posY)
  const isFalling = posY < gridaZemMario;
  if (isFalling) {
    velocityY += deltaTime * 0.003;
  } else {
    velocityY = 0;
    posY = gridaZemMario;
  }

  console.log (gridaZemMario)


  const bloksVirsMario = findBlockAbove(posX, posY);




  const bloksPaLabi = findBlockRight(posX, posY);
  if (posX>bloksPaLabi){
    posX=bloksPaLabi;
  }

  const bloksPaKreisi = findBlockLeft(posX, posY);
  if (posX<bloksPaKreisi){
    posX=bloksPaKreisi;
  }


  if (posY>410 && posX<100 && posY<600 ){
    posY=410;
    velocityY=0
  }


  const isMovingUp = keysPressed.indexOf("ArrowUp") > -1;
  if (isMovingUp && !isFalling) {
    velocityY = -1.5;
//    posY -= deltaTime * 4;
  }

  posY += deltaTime * velocityY;

}

1 Ответ

0 голосов
/ 30 апреля 2020

Я не уверен, что вы пытаетесь достичь, поэтому, возможно, я неправильно понял ваш вопрос, но ваш const map - это просто массив, который имеет только одномерный индекс x. В вашем function findBlockUnder(posX: number, posY: number) вы передаете x и y.

. Вам может понадобиться матрица типа const map = [][]?

. Кроме того, все, что делает ваша функция findBlockUnder, возвращает первый результат вашего массива, потому что return оставит ваш для l oop рано и, следовательно, не l oop через весь массив

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...