;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL

Topo

OPINIÃO

The Last of Us Parte II é marcante até de olhos fechados

The Last of Us Parte II, do estúdio Naughty Dog, tem diversos recursos de jogabilidade para auxiliar deficientes visuais - Divulgação/Sony
The Last of Us Parte II, do estúdio Naughty Dog, tem diversos recursos de jogabilidade para auxiliar deficientes visuais Imagem: Divulgação/Sony

João Varella

Colaboração para o START

19/09/2020 04h00

Joguei The Last of Us Parte II com os olhos fechados. Pela primeira vez, usei as ferramentas de ibilidade oferecidas por um game.

Antes de relatar a experiência, dois avisos: os recursos de ibilidade foram pensados para atender pessoas com deficiência visual. A intenção deste artigo é apontar para os jogadores em geral uma nova forma de se experienciar esse que é um dos grandes lançamentos recentes.

Segundo recado: falarei sobre as primeiras horas do jogo e algumas mecânicas, o que pode ser entendido como spoilers. Tentei deixar o relato de certos momentos do jogo sem muitos detalhes para não prejudicar quem ainda não jogou, mas com elementos suficientes para localizar quem já ou pelo game.

The Last of Us II com olhos vendados - João Varella/Arquivo pessoal - João Varella/Arquivo pessoal
O repórter testando The Last of Us II de olhos vendados
Imagem: João Varella/Arquivo pessoal

Anteriormente, em The Last of Us...

The Last of Us Parte II (ou TLOU2) é a continuação de um dos jogos mais importantes da década ada. Em 2013, o estúdio Naughty Dog adotou a base da jogabilidade de sua série Uncharted para contar a intensa jornada de Joel e Ellie em meio a uma América arrasada por um vírus que controla o comportamento dos humanos. Dá para chamar a ambientação de The Last of Us de apocalipse zumbi, porém com ênfase ao aspecto humano e social. Em termos cinematográficos, é mais David Cronenberg do que George A. Romero.

A continuação chamou a atenção por muitos aspectos, entre eles as ferramentas de ibilidade, com dezenas de opções e configurações:


Por postagens como essa do Ruhan Gonçalves, fiquei motivado em experimentar jogar sem ver. Dá certo?

Não havia jogado TLOU2 antes, então teria uma experiência pura. Bem, já havia assistido aos trailers e conheço os jogos anteriores da desenvolvedora, portanto tenho familiaridade com as propostas da Naughty Dog. Fora isso, nada; não fiz parte do hype do lançamento, em junho deste ano.

Ao abrir o jogo pela primeira vez, surgem as opções de ibilidade logo de início. Liguei o conjunto pré-estabelecido de configurações de ibilidade recomendadas de visão e cobri os olhos.

Primeiros os

The Last of Us II - Divulgação/Sony - Divulgação/Sony
"Joel, é você">var Collection = { "path" : "commons.uol.com.br/monaco/export/api.uol.com.br/collection/start/primeira-pessoa/data.json", "channel" : "start", "central" : "start", "titulo" : "Primeira Pessoa", "search" : {"tags":"79816"} };