Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[AS3] Instances maken van Shape

Pagina: 1
Acties:

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Ik bereken tijdens run-time de vorm van een kubus, vanuit een bepaald perspectief. Met de drawing functies kan ik dan de kubus tekenen in een Shape.

Nou zijn, in het geval van isometrisch perspectief, alle kubussen hetzelfde. Ik hoef er dus eigenlijk maar één te tekenen, waarna ik de Shape zou willen kopiëren. Eigenlijk wil ik dus instances maken van een tijdens runtime getekende Shape. Is dat mogelijk met Actionscript 3?

TabCinema : NiftySplit


Verwijderd

ehm zou normaal wel gewoon moeten gaan. Ik weet nu niet exact hoe je code er uitziet en dergelijke, en hoe je kennis is van AS3, maar instances maken is gewoon basic stuff (ik neem aan dat je dit zelf ook wel weet). Of de berekening van de kubus tijdens runtime het proces bemoeilijkt durf ik niet zeggen, maar mijn gok is dat het gewoon kan.

Misschien wat code posten?

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Flash ActionScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var square1:Shape = new Shape();
square1.x = 0;
square1.y = 0;
square1.graphics.lineStyle(1,0x000000,1);
square1.graphics.beginFill(0xFF0000,1);
square1.graphics.drawRect(0,0,100,100);
square1.graphics.endFill();

var square2:Shape = square1;    //this passes square1 by reference.
square2.x = 100;                //position of square1 is also affected
square2.y = 100;

stage.addChild(square1);
stage.addChild(square2);


Ik wil dus dat square2 dezelfde graphics heeft als square1. Ik zoek dus een soort van Clone() of Duplicate() method.

TabCinema : NiftySplit


Verwijderd

Voor zover ik weet bestaat er geen Clone method oid, maar deze kan je makkelijk zelf maken. Hoe je het nu doet lijkt me wat omslachtig, met die square2 dingen.

Je kan volgens mij gewoon beter een functie maken die de squares op de stage plaatst. Als parameters geef je dan gewoon de x en y coordinaten mee, en in de functie doe je gewoon addChild(square1). Maakt het meteen ook weer wat dynamischer.

dus iets als

Flash ActionScript 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
var square1:Shape = new Shape();
square1.x = 0;
square1.y = 0;
square1.graphics.lineStyle(1,0x000000,1);
square1.graphics.beginFill(0xFF0000,1);
square1.graphics.drawRect(0,0,100,100);
square1.graphics.endFill();

private function addRect(_posX:int, _posY:int):void{
addChild(square1);
square1.x = _posX;
square1.y = _posY;
}


als je dan je vierkanten wil toevoegen, moet je gewoon die functie addRect() met de juiste parameters doorgeven. Dit kan met de hulp van een loop, eventlistener en dergelijke, als je een beetje actionscript kent vertel ik je niets nieuws natuurlijk :). Je hoeft niet voor iedere instance een nieuwe variabele te declareren he :).

Die code is trouwens onder voorbehoud van fouten, heb het even los uit het polsje getypt, en men reply is natuurlijk ook onder voorbehoud van een totaal verkeerde opvatting van mezelf, en van de kennis van je actionscript die ik misschien verkeerd inschat. Ik zou me nogal lullig voelen als ik hier basic stuff aan een pro aan het uitleggen ben :P

[ Voor 7% gewijzigd door Verwijderd op 22-04-2008 20:13 ]


  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Ik ben geen pro hoor, en alle hulp is natuurlijk welkom. Ik moet zeggen dat ik jouw code niet helemaal begrijp. Op welk object wordt de addChild method uitgevoerd? Gaat dit überhaupt werken?

Ik kan 1 shape op geen enkele manier twee keer op de stage krijgen zonder hem opnieuw te tekenen. Een tweede keer addChild aanroepen oid zorgt ervoor dat de eerste instance verdwijnt.

Kun je proberen een werkend stukje code te maken?

TabCinema : NiftySplit


Verwijderd

Flash ActionScript 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// ActionScript file
package{
    import flash.display.Shape;
    import flash.display.Sprite;
    
    public class Shapes extends Sprite{
        
        private var _rectangle:Shape;
        private var _counter:int = 3;
        private var _posX:int = 50;
        private var _posY:int = 50;
        
        public function Shapes(){
            for (var i:int = 0; i< _counter; i++){
            _rectangle = new Shape();
            _rectangle.graphics.lineStyle(1, 0xFF00FF, 1);
            _rectangle.graphics.beginFill(0xAAAAAA);
            _rectangle.graphics.drawRect(_posX, _posY, 150, 100);
            _rectangle.graphics.endFill();
            addChild(_rectangle);
            _posX += 175;
            trace("testje");
            }
        
        }
    }
}


Dit is allemaal redelijk basic. Deze is gratis ;). Maar ik stel wel voor dat je jezelf even verdiept in de Children functies, best wel krachtige functies (ik moet toegeven, zelf ben ik er ook nog geen expert in).

Als je in de code de waarde van _counter veranderd, kan je hem zoveel keer als je wil op je stage krijgen. Ook _posX en _posY kan je aanpassen, al dan niet in de loop. Misschien was het bij jou ook al gelukt omdat je tweemaal addChild aanriep, maar lagen deze gewoon bij elkaar. Onthou ook dat de trace() functie erg handig is als je je stappen wil doorlopen.

Om op je vraag te antwoorden: addChild wordt op het object _rectangle uitgevoerd (in mijn code dus), wanneer je addChild() gebruikt ga je van dat object instances maken, instances zijn dus de zichtbare varianten die je van het object maakt. Hopelijk ben je er wat mee :)

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Dit is de methode zoals ik die nu gebruik. Je maakt zo echter geen instances: je voert gewoon dezelfde tekenfunctie meerdere keren uit. Dat lijkt mij nogal inefficient: ik wil gewoon de uiteindelijke vorm kopieëren, en niet de onderliggende tekeninstructies nogmaals uitvoeren.

De vraag is dus of dat überhaupt mogelijk is :)

Ik gebruik zelf trouwens altijd this.method() binnen classes, maar dat is misschien een kwestie van smaak. Vandaar dat ik je eerdere code niet begreep. Bedankt voor de moeite iig.

TabCinema : NiftySplit


Verwijderd

Ehm voor zover ik weet maak je zo toch wel instances aan van een object. Zo is het mij toch aangeleerd. Ik heb het nu in een loopje gezet zodat je kon zien dat dit mooi uitbreidbaar is, maar dit kan ook gewoon op andere manieren, alleszins via addChild. Het is natuurlijk een ander verhaal als je verschillende vormen wil, maar dan maak je ook instances van een nieuw object aan.

De uiteindelijke vorm kopieren is dus mogelijk, en volgens mij op deze manier, wel degelijk via instances toe te voegen :).

Misschien afwachten op een reactie van een derde persoon, ik denk dat minstens 1 van ons de bal compleet misslaat, of gewoon allebei :p

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Ja, zonder twijfel maak je kopieën van het object. Het werkt zo ook prima, maar voor mn gevoel moet het sneller kunnen door het object zeg maar in zn geheel te kopieëren. Dan hoeven bijvoorbeeld de grenzen van de fill niet meer berekend te worden.

Helaas zijn er hier niet erg veel AS3 mensen te vinden volgens mij...

TabCinema : NiftySplit


Verwijderd

Bozozo schreef op woensdag 23 april 2008 @ 12:33:

Helaas zijn er hier niet erg veel AS3 mensen te vinden volgens mij...
Nee blijkbaar niet nee, of ze negeren dit topic misschien wegens te simpel? :+

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Nou voorlopig is mn vraag nog niet beantwoord dus dat zal wel meevallen :P

TabCinema : NiftySplit


  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Bozozo schreef op woensdag 23 april 2008 @ 13:10:
Nou voorlopig is mn vraag nog niet beantwoord dus dat zal wel meevallen :P
zoiets?
http://niko.informatif.or...20_clone_an_object_in_as3

Programmer - an organism that turns coffee into software.


  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Hmm, ik heb dit geprobeerd:
Flash ActionScript 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var square1:Shape = new Shape();
square1.x = 0;
square1.y = 0;
square1.graphics.lineStyle(1,0x000000,1);
square1.graphics.beginFill(0xFF0000,1);
square1.graphics.drawRect(0,0,100,100);
square1.graphics.endFill();

var r : ByteArray = new ByteArray ();
r.writeObject(square1);
r.position = 0;
var clone : *;
clone = r.readObject() as Shape;

var square2:Shape = clone;
square2.x = 100;
square2.y = 100;

stage.addChild(square1);
stage.addChild(square2);


Resultaat:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Untitled_fla::MainTimeline/Untitled_fla::frame1()


Deze foutmelding is het resultaat van de uitrukking '... as Shape'. Als ik dat weghaal krijg ik:

TypeError: Error #1034: Type Coercion failed: cannot convert Object@2c764a1 to flash.display.Shape.
at Untitled_fla::MainTimeline/Untitled_fla::frame1()


Uiteraard geldt die voor 'var square2:Shape = clone;'

Het lijkt er dus op dat Shapes zich niet op deze manier laten kopieëren, of ik heb te veel van de functie weggelaten.

TabCinema : NiftySplit


  • compufreak88
  • Registratie: November 2001
  • Laatst online: 02-05 17:51
Kun je misschien is kijken naar de flyweigt pattern?

Wat je dan doet is 1 instance maken van de shape, maar die heeft geen state members. Vervolgens maak je een composite class die dan alle states bijhoudt van je apparte shapes.

Link

  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Het idee van zo'n flyweight is precies wat ik bedoel. In feite doe ik zoiets nu al:

Camera draait:
1. Bereken hoe de x,y,z basisvectoren moeten worden geprojecteerd op het scherm.
2. Bereken de ligging van alle hoekpunten van een kubus, met deze basisvectoren.
3. Sorteer de tekenvolgorde (dus z-index) van de zijvlakken op basis van de afstand tot de camera.
4. Update alle kubussen in beeld. Momenteel wordt elke kubus gewoon opnieuw getekend. Dit moet volgens mij dus sneller kunnen, omdat elk tekeningetje hetzelfde is.

Elk frame:
1. Bereken de posities van alle kubussen op het scherm
2. Sorteer de z-index van de kubussen op basis van de afstand tot de camera.

Alle kubussen hebben dus gedeelde eigenschappen, en het uiterlijk van de kubus wordt maar 1x bepaald. In die zin kun je al van zo'n flyweight constructie spreken. Alleen stap 4 zit me niet lekker, dat lijkt zo enorm inefficient.

Overigens besefte ik vanmiddag dat AS3 onder WEB valt, niet onder PRG.

TabCinema : NiftySplit


  • TheBorg
  • Registratie: November 2002
  • Laatst online: 18-11 15:25

TheBorg

Resistance is futile.

Tijd om OOP te gaan programmeren.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package
{
    public class Cube extends Shape
    {
        public function set x()
        {
            
        }

        public function set y()
        {
            
        }
        
        public function drawit()
        {
            parent.addChild(this);
        }
    }
}


code:
1
2
3
4
5
6
7
8
9
var square1:Cube = new Cube();
square1.x = 0;
square1.y = 0;
square1.drawit();

var square2:Cube = new Cube();
square2.x = 0;
square2.y = 0;
square2.drawit();


Kijk eens in de manual of op internet voor voorbeelding/tutorials.


-edit-
Bozozo schreef op woensdag 23 april 2008 @ 22:45:
Alleen stap 4 zit me niet lekker, dat lijkt zo enorm inefficient.
Maak je geen zorgen, dat kan makkelijk.

[ Voor 39% gewijzigd door TheBorg op 23-04-2008 23:00 ]


  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Hmm, het te-weinig-code-gepost effect :P

Ik werk al OO en ik heb ruime ervaring met AS3. Ik ben op zoek naar een efficientere manier om een shape te kopieëren, niets meer en niet minder.
Maak je geen zorgen, dat kan makkelijk.
De vraag is niet of het kán, de vraag is of het sneller kan. Ik wil dat het beeld soepel te draaien is met ongeveer honderd kubussen in beeld.

Zie hier een demo van waar ik nu ben. Het loopt al redelijk maar rond de honderd kubussen krijgt mijn processor het moeilijk. Z-indexing gaat ook nog flink wat power vreten denk ik, dus elke prestatiewinst is welkom.

TabCinema : NiftySplit


  • TheBorg
  • Registratie: November 2002
  • Laatst online: 18-11 15:25

TheBorg

Resistance is futile.

Laat me even over die performance nadenken. Ik heb wel een clone functie, die zal ik even opzoeken.

-edit-
Mijn clone functie gebruikt mx.utils.ObjectProxy en dat zit alleen in Flex. Verder denk ik niet dat clonen performancewinst gaat opleveren, misschien is het zelfs wel langzamer dan opnieuw tekenen.

Hou er ook rekening mee dat Flash geen hardware video acceleratie heeft, wat betekend dat alles wat op het scherm gebeurd meestal het "zwaarste" is. Als ik in of uitzoem gaat alles een stuk soepeler, wat zou betekenen dat niet je berekeningen de limiet zijn, of het trekken van de lijnen, maar wat er op het scherm gebeurd (moeilijk uit te leggen wat het verschil is tussen het trekken van lijnen en wat er op het scherm gebeurd). Alle AS wordt uitgevoerd voor de screen update, en volgensmij heeft ie daar totaal geen moeite mee.

[ Voor 78% gewijzigd door TheBorg op 24-04-2008 01:43 ]


  • Stukfruit
  • Registratie: Oktober 2007
  • Niet online
Inderdaad, hier heb ik nu al 130 kubussen (allemaal op het scherm), maar het processorverbruik is op het moment nog maar rond de 30%, inclusief andere achtergrondprocessen die er nog bij draaien.

Ik vrees idd dat je een snellere CPU zal moeten vinden als je het sneller wil hebben :)
"kijk mij eens patsen met mijn snelle C2D :+ "
Bozozo schreef op woensdag 23 april 2008 @ 23:59:
Het loopt al redelijk maar rond de honderd kubussen krijgt mijn processor het moeilijk. Z-indexing gaat ook nog flink wat power vreten denk ik, dus elke prestatiewinst is welkom.

Dat zit wel Schnorr.


  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Hey, jullie hebben gelijk wat flash betreft. Het renderen van het uiteindelijke beeld is de bottleneck; mijn berekeningen zijn nauwelijks merkbaar.

Bewijs: nieuwe versie techdemo

Resize je venster, zoom uit of verlaag de qualiteit. Zo haal ik nog 50 fps bij 200 cubes.

Note: z-indexing was een eitje :*)

[ Voor 4% gewijzigd door Bozozo op 24-04-2008 14:54 ]

TabCinema : NiftySplit


  • TheBorg
  • Registratie: November 2002
  • Laatst online: 18-11 15:25

TheBorg

Resistance is futile.

Het ziet er vet uit maar wat ben je eigenlijk aan het maken?

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Bozozo schreef op donderdag 24 april 2008 @ 14:53:
Hey, jullie hebben gelijk wat flash betreft. Het renderen van het uiteindelijke beeld is de bottleneck; mijn berekeningen zijn nauwelijks merkbaar.

Bewijs: nieuwe versie techdemo

Resize je venster, zoom uit of verlaag de qualiteit. Zo haal ik nog 50 fps bij 200 cubes.

Note: z-indexing was een eitje :*)
Hoe?

* LuCarD gaat bij een volgende project z-index nodig hebben ....

Frame rate van -0.36
Met 446 cubes :)

[ Voor 3% gewijzigd door LuCarD op 24-04-2008 15:07 ]

Programmer - an organism that turns coffee into software.


  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Flash ActionScript 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            //called on every new frame
            this.zindexarray = [];
            
            for (var i:uint = 0; i < this.nr_of_objects;i++) {
                var xyzpos:Array = this.objects[i].getPosition();
                var uvdpos:Array = xyz2uv(xyzpos[0],xyzpos[1],xyzpos[2]);
                objects[i].x = uvdpos[0];
                objects[i].y = uvdpos[1];
                this.zindexarray.push({"objectnr":i,"depth":uvdpos[2]});
            }
            
            this.zindexarray.sortOn("depth",Array.NUMERIC,Array.DESCENDING);
            for (i = 0; i < this.nr_of_objects;i++) {
                canvas.setChildIndex(objects[this.zindexarray[i]["objectnr"]],i);
            }

xyz2uv past lineaire transformaties toe om een 3D punt te projecteren op het cameravlak.

Oh, en het doel is nog een beetje vaag. Het gaat een soort 3D tetris worden, gebaseerd op Human Tetris (zie youtube).

TabCinema : NiftySplit


  • Stukfruit
  • Registratie: Oktober 2007
  • Niet online
Misschien een idee om er een shortcut bij te gooien om zelf het aantal kubussen te verhogen/verlagen? Zou me wel handig lijken voor het getest :)

Je teksten worden trouwens achter de kubussen getekend :)

Dat zit wel Schnorr.


  • Bozozo
  • Registratie: Januari 2005
  • Laatst online: 20-02 16:10

Bozozo

Your ad here?

Topicstarter
Ik denk dat ik voorlopig niet meer in deze vorm hoef te testen, dus ik ga het testprogramma niet uitbreiden.

Nog een updatetje voor LucarD:

Flash ActionScript 3:
1
2
3
4
5
6
7
8
9
10
11
12
13
            //called on every new frame 
            for (var i:uint = 0; i < this.nr_of_objects;i++) {
                var xyzpos:Array = this.objects[i].getPosition();
                var uvdpos:Array = xyz2uv(xyzpos[0],xyzpos[1],xyzpos[2]);
                objects[i].x = uvdpos[0];
                objects[i].y = uvdpos[1];
                this.zindexarray[i] = {"objectnr":i,"depth":uvdpos[2]};
            }
            
            this.zindexarray.sortOn("depth",Array.NUMERIC,Array.DESCENDING);
            for (i = 0; i < this.nr_of_objects;i++) {
                canvas.setChildIndex(objects[this.zindexarray[i]["objectnr"]],i);
            }


...scheelt weer wat geklooi aan het zindex array. Zal vast wel iets sneller zijn :P

TabCinema : NiftySplit

Pagina: 1