PDA

Volledige versie bekijken : Opzetten van boundaries


Crypt36
%Europe/Berlin %302 %2009, 08:15
Ik probeer een boundary op te zetten voor een bepaald vlak op mijn stage. het vlak heeft hoekpunten x=50, x=450, y=50, y=450.

En ik heb een blokje dat met telkens x=50 vooruitspringt.

if(blok.x > 450 || blok.x < 50 || blok.y < 50 || blok.y > 450){
if (keyPressedUp) {
blok.moveForward(60);
}

Het probleem is dat blok telkens met 50 vooruitspringt en dus in het vlak of op de rand komt en vast komt te zitten. Ik heb dit eerder met een hittest gedaan en die stuurde blok dan telkens een stukje terug uit het vlak maar dat wil ik niet, het is een muur en je loopt ertegenaan -> stop.

Dit is een heel bekend probleem neem ik aan maar kan het niet vinden en zit maar te tobben. Ik wil geen gebruik maken van een hittest aangezien het vlak geen object is en ik ook niet overal transparante gifjes op mijn stage wil plaatsen!

Sjoedzj
%Europe/Berlin %359 %2009, 09:37
Zit het probleem niet in het feit dat je blok.x en blok.y coordinaat een vast punt is in je blok (zeg 0,0)? Je zult dus rekening moeten houden met de breedte en hoogte van je blok.

Crypt36
%Europe/Berlin %365 %2009, 09:45
Na nog meer tobben heb ik dit verzonnen wat werkt alleen is het probleem nog gecompliceerder met nog meer ifs en variabelen vrees ik maar het gaat me lukken haha dit is ieg de oplossing voor mijn vraag (met andere getallen wel)

if(blok.y + 60 >= 1030 && blok.x > -350 && blok.x < 350){

blok.y+=((blok.y + 60) -1030 );
}
else{
blok.y +=60
}


Heel makkelijk maar het moet je maar weer net te binnen schieten....

Midas
%Europe/Berlin %365 %2009, 09:46
Kijk eens naar dit script. Ik weet niet precies hoe je werkt met keys in AS3 maar dit werkt:

var key:uint = undefined;
var dirX:int = 0;
var dirY:int = 0;
var step:uint = 50;
var boundaries:uint = 50;
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function keyPressed(e:KeyboardEvent):void {
if (e.keyCode >= 37 && e.keyCode <= 40) {
key = e.keyCode;
}
}
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
function keyReleased(e:KeyboardEvent):void {
key = undefined;
dirX = 0;
dirY = 0;
}
blok.addEventListener(Event.ENTER_FRAME, moveBlok);
function moveBlok(e:Event):void {
switch (key) {
case 38 :
//trace("Key.UP");
dirY = -1;
break;
case 39 :
//trace("Key.RIGHT");
dirX = 1;
break;
case 40 :
//trace("Key.DOWN");
dirY = 1;
break;
case 37 :
//trace("Key.LEFT");
dirX = -1;
break;
}
e.target.x += step * dirX;
e.target.y += step * dirY;
e.target.x = Math.min(Math.max(e.target.x, boundaries), stage.stageWidth - e.target.width - boundaries);
e.target.y = Math.min(Math.max(e.target.y, boundaries), stage.stageHeight - e.target.height - boundaries);
}

De oorsprong van de movieclip staat in dit geval in de linkerbovenhoek.

Die Math.min(Math.max(x, y), z) kan je zien als een verkorte notatie van dit:
if (e.target.x <= boundaries) {
e.target.x = boundaries;
} else if (e.target.x >= stage.stageWidth - e.target.width - boundaries) {
e.target.x = stage.stageWidth - e.target.width - boundaries;
}
if (e.target.y <= boundaries) {
e.target.y = boundaries;
} else if (e.target.y >= stage.stageHeight - e.target.height - boundaries) {
e.target.y = stage.stageHeight - e.target.height - boundaries;
}

jaspermuts
%Europe/Berlin %444 %2009, 11:40
@Midas: Ik kan het boundaries-verhaal niet zo geweldig volgen, maar dat geloof ik wel, alleen vermoed ik dat de afhandeling van keys beter is zoals Crypt36 ze gebruikt, dat is ook de meestegebruikte manier.
Jouw versie maakt het namelijk onmogelijk om 2 toetsen tegelijk in te drukken. Soms wil je bijvoorbeeld ook schuin kunnen lopen of bijvoorbeeld rennen met shift + richting.
De gebruikelijke manier is dus: voor elke toets een boolean maken (zoals keyPressedUp voor pijltje omhoog), en in een enter frame handler via een if-statement (geen switch) checken of hij moet uitgevoerd worden. if-else combinaties gebruik je alleen bij 'tegenstrijdige' toetsen, zoals wanneer links en rechts allebei zijn ingedrukt.

Crypt36
%Europe/Berlin %454 %2009, 11:54
Dankjewel Midas maar heb het voor het gemak ik x en y gezet maar het is eigenlijk voor de z as bedoeld dus stage.width en height is niet zo handig. Maar ik heb hem zo moet alleen nog rekening gaan houden met het verschuiven van de camera.z bij draaien.

Dit gebruik ik nu voor het keyboard en werkt super en makkelijk uit te breiden:


static const RIGHT = 37;
static const LEFT = 39;
static const UP = 38;
static const DOWN = 40;
var keyPressedRight:Boolean;
var keyPressedLeft:Boolean;
var keyPressedUp:Boolean;
var keyPressedDown:Boolean;




function keyDownListener(e:KeyboardEvent):void {
switch (e.keyCode) {
case LEFT:
keyPressedRight=true;
break;
case RIGHT:
keyPressedLeft=true;
break;
case UP:
keyPressedUp=true;
break;
case DOWN:
keyPressedDown=true;
break;

}



}








function keyUpListener(e:KeyboardEvent):void {
switch (e.keyCode) {
case LEFT:
keyPressedRight=false;
break;
case RIGHT:
keyPressedLeft=false;
break;
case UP:
keyPressedUp=false;
break;
case DOWN:
keyPressedDown=false;
break;

}
}





if (keyPressedRight) {
camera.yaw( 8);
}else if(keyPressedLeft) {
camera.yaw( -8);
}
if (keyPressedUp) {
camera.moveForward(60);
}else if(keyPressedDown) {
camera.moveBackward(60);
}

Jan
%Europe/Berlin %481 %2009, 12:33
Het probleem is dat blok telkens met 50 vooruitspringt en dus in het vlak of op de rand komt en vast komt te zitten. Ik heb dit eerder met een hittest gedaan en die stuurde blok dan telkens een stukje terug uit het vlak maar dat wil ik niet, het is een muur en je loopt ertegenaan -> stop.

Dit is een heel bekend probleem neem ik aan maar kan het niet vinden en zit maar te tobben.
Als je object voorbij de grens komt (maakt niet uit hoeveel) dan zet je hem op de grens.
Anders ga je 'heen en weer vast te komen' zitten in die hitTest.

mc.y=25
//in een herhalende functie:
mc.y-=50;
if(mc.y <0) mc.y=0;

Groeten;
Jan

jaspermuts
%Europe/Berlin %482 %2009, 12:34
Ja, dat is de gebruikelijke manier voor keyhandling. Het is alleen wel overbodig om zelf constantes als RIGHT en LEFT te maken, omdat deze ook in de Keyboard-class staan.
Je kan het nu laten staan natuurlijk, het maak niet veel uit, maar als je de volgende x veel keycodes wil testen hoef je niet zelf de code uit te vinden, gebruik gewoon bijvoorbeeld Keyboard.RIGHT en Keyboard.LEFT, als het goed is zie je alle mogelijkheden verschijnen als je 'Keyboard.' typt (deze class importeer je via flash.ui.Keyboard).

Crypt36
%Europe/Berlin %619 %2009, 15:52
Ik snap er helemaal niks van. Zit al de hele dag rond die **** 3d kamer bestaande uit 4 muren te lopen een goede hittest uit te vinden zodat ik niet door de muren kan maar het werkt allemaal totaal niet.

Ik wil dus toch met een hittest werken. Maar een hittest werkt alleen als 2 objecten elkaar hitten. Dus als ik tegen een muur aanloop en er moet een hittest komen moet ik een object meeslepen. Lekker simpel toch? Dus heb ik een plane aangemaakt van 100x100 en die de x,y en z van mijn camera gegeven.

Met mijn camera ga ik naar voren en naar achter door z space. Maar hoe groot of hoe klein ik dat plaatje ook maak ik krijg altijd een hittest op 380z van de muur af en het is gewoon totaal niet logisch?! Hoe komt dit?!

Mijn logica was dat als ik een plane van 100x100 in een 90graden Y rotation aan mijn camera heb zitten dat hij telkens een hittest geeft op 50 afstand aan alle kanten van mijn camera. Maar dit is dus 380 afstand wat ik ook doe. Ook als ik het de afmetingen 1x1 geef.

Ik betwijfel of iemand dit verhaal snapt, hoe zouden jullie een hittest met een muur in x,y en z doen?


primitive1 = new Plane(material, 700, 300, 4, 4);
primitive1.z=1100;
primitive1.x=0;
primitive1.y=0;
scene.addChild(primitive1);


wallblock = new Plane(wallq, 100, 100, 1, 1);
scene.addChild(wallblock);


function onEnterFrame(e:Event):void
{

if (keyPressedUp) {
trace(camera.z)
if(wallblock.hitTestObject(primitive1) ==false){

camera.moveForward(40);
}


wallblock.z=camera.z;
wallblock.x=camera.x;
wallblock.y=camera.y;



renderer.renderScene(scene, camera, viewport);
}



Edit:

Ik neem aan dat die hittest gewoon niet met de z coordinaat werkt hoewel ik deze hittest wel van een PV3D guide met 2 spheres heb. Ik weet het anders ook echt niet.

Heb het nu opgelost met de post van adnez:


if (keyPressedUp) {
trace(camera.z)
if(camera.z + 40 >= 1000 && camera.z < 1100 && camera.x > -350 && camera.x < 350){

camera.z=998;
camera.moveForward(10)
}

else{ camera.moveForward(40)

}