[arrays] push bij te kleine/grote waarde

Status
Niet open voor verdere reacties.

That Guy

Meubilair
Lid geworden
28 nov 2006
Berichten
5.010
Ben ik weer :p


Deze keer een vraag over arrays: voor de JTile engine probeer ik nu een scrollende map te realiseren.
Leuk en aardig allemaal, maar ben even begonnen met een test. zie hier: http://www.vegras-studios.com/x/tile/xdev/scrolltile/?x=0&y=0 .
In de url kan je de x en y veranderen. Javascript staat allemaal in de head van de pagina.

Het probleem: omdat je 'buiten de array' kan treden met het bewegen (cq. een waarde groter dan 4 kiezen voor x of y) krijg je natuurlijk dat de array undefined is. Leuk, maar voor de x-waardes heb ik dat opgelost. probeer bv. eens een x van -8 of 8.

De y-waardes zijn een stuk lastiger, dus dacht ik, daar kan je mooi push voor gebruiken. Maar, mooi niet dus.


Heeft iemand een idee hoe ik dit het makkelijkste kan oplossen (refereer even naar de broncode van het bestand) of mischien een geheel makkelijkere oplossing voor dit probleem?



Logica, blijft vervelend :p

Alvast bedankt, groet, V. :thumb:
 
Je kunt wel de array uitbreiden, maar opzich kan je beter een functie maken die de waarde uit de map leest of zwart returned als het buiten de array ligt. Dat scheelt ruimte in de array, en dus geheugen als een of andere grapjas y = 23783763 invult (ookal heeft ie alleen zichzelf ermee).

Code:
function readTile(map, y, x)
{
  if (!map[y] || !map[y][x])
[COLOR="Red"]// Belangrijk! "if (!map[y][x])" werkt niet wanneer Y te hoog is. Javascript crasht aangezien map[y] niet bestaat en dus map[y][x] niet kan lezen.[/COLOR]
    return 'black';
  return map[y][x];
}

en dan kun je hier de functie gebruiken in plaats van rechtstreeks uit de uit de array lezen:
document.write('<img src="' + temparr[y][x] + '.bmp">');
wordt dan
Code:
document.write('<img src="' + readTile(temparr, y, x) + '.bmp">');

Heb ook meteen temparray eruit gesloopt, die is niet meer nodig met de functie aangezien map1 niet aangepast hoeft te worden. Dit werkt bij mij iig.
Code:
<html>
<head>
<base href="http://www.vegras-studios.com/x/tile/xdev/scrolltile/" />
<script type='text/javascript'>

function readTile(map, y, x)
{
  if (!map[y] || !map[y][x])
    return 'black';
  return map[y][x];
}


var map1 =
	[
		['red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','yel','blu','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','blu','yel','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','gre','red'],
		['red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red','red']
	];


function drawWholeMap()
{
  document.write('Showing full map:<br />');
  var x;
  var y;

  for(y=0;y<20;y++)
  {
    for(x=0;x<20;x++)
    {
      document.write('<img src="' + readTile(map1, y, x) + '.bmp">');
    }
    document.write('<br />');
  }
}

drawWholeMap();
document.write('<br /><br /><br />');



function _(fromX,fromY)
{
  //draw the map starting with coors x,y
  //good luck xD

  var mX = 16;
  var mY = 16;
  var x;
  var y;
   
  document.write('<br />Showing map from x=' + fromX + ' and y=' + fromY + '<br />');

  for(y=0;y<mY;y++)
  {
    for(x=0;x<mX;x++)
    {
      document.write('<img src="' + readTile(map1, [COLOR="Red"]y+fromY, x+fromX[/COLOR]) + '.bmp">');
    }
    document.write('<br />');
  }

}


<?php echo "_({$_GET["x"]},{$_GET["y"]});"; ?>

</script>
</head>


<body>
</body>

</html>
 
Laatst bewerkt:
Glest,

Alweer heel erg bedankt, het werkt!
De regel met ' if (!map[y] || !map[y][x])' was precies wat ik zocht! Helemaal goed.

De temp-array had ik eerst alleen omdat ik wel wilde weten op welke x/y locatie je zit, maar dit kan je natuurlijk ook berekenen door de 'fromX' en 'fromY' ervan af te halen.


:thumb:
 
Had het eerst zelf ook niet door:p

Ik bedenk me nu dat dit ook kan trouwens:

Code:
function readTile(map, y, x)
{
  var output;
  try
  {
    output = map[y][x];
  }
  catch(e)
  {
    output = 'black';
  }
}

Het ziet er wat slordiger uit vind ik zelf maar het zou best eens sneller kunnen zijn. Niet dat het veel uit maakt bij een simpele check als dit :p
 
niet helemaal, want krijg nu 'undefined' plaatjes (geen js error echter)

zie http://localhost:8080/?x=5&y=10

PHP:
//js

  var output;
  try
  {
    output = map[y][x];
  }
  catch(e)
  {
    output = 'black';
  }


return output;


geeft problemen in de x-richting. Snap niet waarom.... ^_^" ... catch werkt wel (wordt wel aangeroepen, gechecked met alert) maar het zetten van de output werkt niet.


:thumb:
 
Laatst bewerkt:
hmm een vaag trekje van javascript vindt ik zelf, maar het komt (na wat testen) doordat je wel een undefined object kan lezen, maar zodra je probeert een sub-variable (of array element) te lezen van het undefined object gaat het fout.

Dus zolang y bestaat maar x niet is er geen javascript fout en dus ook geen exceptie voor het catch blok... Dan denk ik toch dat de eerste methode het beste is :(
 
hm, tsja. Even wat vogelen met throw() dan maar. :thumb:


[edit]
yup, dit werkt, maargoed, niet heel mooi.
PHP:
//js

function readTile(map, y, x)
{

  var output;
  try
  {
    if(map[y] && !map[y][x]){    //map[y] bestaat, maar map[y][x] niet
        throw('y & !x');               //verzin wat leuks
    }
    output = map[y][x];
  }
  catch(e)
  {
    output = 'black';
  }


return output;
nogmaals erg bedankt.[/edit]
 
Laatst bewerkt:
mja maar nu is het niet meer sneller dan de eerste manier. Erg veel maakt het zoiezo niet uit. Het is alleen jammer dat je een ongedefineerd array element kunt lezen.

Maarja, ik zou het maar gewoon bij de eerste manier houden. Hij werkt en de snelheidsverschillen waar het om gaat zijn zoiezo miniem. Dan kun je toch maar het beste je code leesbaar houden.
 
yea, was ik ook vna plan. 3 regels is een stuk netter :p


^&%^$javascript xD

[edit]
hoe kan je het makkelijkste javascript script snelheden meten? [/edit]
 
lol, inderdaad.

de enige manier die ik ken om snelheden te meten is met date.getTime(). Geeft een Unix timestamp, maar dan in milliseconden. Als je je functie in een grote loop zet (1000 keer herhalen lijkt me meestal genoeg) kun je daarmee wel een redelijk betrouwbare meting doen. Wel een paar keer herhalen natuurlijk :P


/edit: Niet Date.UTC, dateInstance.getTime()
 
Laatst bewerkt:
Hmm ik zat er behoorlijk naast :eek:

De methode met try{ }...catch{ } deed er onder optimale omstandigheden 815 ms over het lezen van 1000 tiles. De methode met het simpele if(!map[y] || !map[y][x]) deed over dezelfde opdracht 2 ms :p

Het ziet er dus niet alleen netter uit, het is ook sneller :thumb:
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan