In deze zelfstudie leer je hoe je de drie verschillende kleurkanalen van een afbeelding kunt scheiden om een RGB-verschuivingseffect te creëren. Ik zal je ook wat grafische trucs tonen om een oud CRT-scherm na te bootsen.
Hier is een voorbeeld van het effect dat we zullen creëren:
De belangrijkste afhaaltijd in deze zelfstudie is het RGB-verschuivende effect, maar ik zal ook laten zien hoe je de CRT-scanlijnen, ruis en roll-barafbeeldingen kunt maken.
Elke afbeelding op uw computerscherm wordt weergegeven met de kleuren rood, blauw en groen. Door deze drie kleuren in verschillende hoeveelheden te mengen, kan uw computer de andere kleuren in het spectrum creëren.
Als de drie kleurkanalen niet goed uitgelijnd zijn, wordt de afbeelding niet correct samengesteld en begint u de randen van de afzonderlijke kanalen uit de zijkanten van de afbeelding te 'bloeden'.
Dit is precies wat we in deze tutorial gaan doen; een afbeelding in de drie kleurkanalen scheiden en vervolgens elk afzonderlijk transformeren om een vervormingseffect te creëren. Laten we ernaar toe gaan!
(Je kunt veel meer leren over hoe RGB-kleuren werken op Wikipedia.)
U moet een afbeelding maken om het effect op toe te passen. Ik heb ervoor gekozen om een videogame-titelscherm te maken, maar je kunt elke gewenste afbeelding maken.
Maak een nieuwe filmclip genaamd 'titleScreen' en zet je titelscherm (of een andere afbeelding) erin.
Ik denk dat iets retro-thema's het beste werkt met dit effect, omdat het me doet denken aan een oud slecht functionerend arcadescherm. Ik heb mijn titelscherm gemaakt met een font met de naam Commodore 64 Pixeled. Ik heb een Glow-filter aan de tekst toegevoegd om het die smeary, geblazen CRT-look te geven.
Als je tevreden bent met je ontwerp, voeg je de titelscherm MovieClip naar het werkgebied en geef het de instantienaam 'titleScreen'.
Maak een nieuw Actionscript-bestand met de naam 'RGBShift.as'. Bewaar dit bestand in dezelfde map als uw hoofd Flash-bestand. Voeg deze code toe om de shell voor de klas te maken:
pakket import flash.display.DisplayObject; import flash.display.Sprite; import flash.display.BitmapData; import flash.display.Bitmap; import flash.display.BitmapDataChannel; import flash.display.BlendMode; import flash.events.Event; import flash.geom.Point; public class RGBShift breidt Sprite uit private var _centerX: Number; privé var _centerY: Number; // CONSTRUCTOR openbare functie RGBShift (dObj: DisplayObject)
Opmerking van de uitgever: Niet comfortabel met klasse-gebaseerde codering tot nu toe? Bekijk deze snelle tip om je op weg te helpen.
Deze code doet nog niets. De eerste 10 regels of zo importeren alle extra klassen die we nodig hebben. Ik heb twee privévariabelen met de naam '_centerX' en '_centerY' (ik gebruik de onderstrepingstekens om privévariabelen aan te duiden). Deze twee variabelen bevatten de x- en y-coördinaten van het midden van onze afbeelding.
Merk op dat de constructorfunctie (leeg voor nu) een DisplayObject accepteert. Hierdoor kunnen we elk type DisplayObject met dit effect gebruiken (MovieClip, Sprite, Bitmap, enz.). We gaan de titelscherm MovieClip van het werkgebied, maar als de klasse een DisplayObject accepteert, blijft het flexibel voor later gebruik.
We hebben onze klasse flexibel gemaakt door het toestaan van elk DisplayObject, maar we zullen een BitmapData-object nodig hebben om het RGB-verschuivende effect te doen. Laten we een functie maken die BitmapData van een DisplayObject kan maken.
Voeg deze functie toe aan uw RGBShift-klasse net onder de constructor:
private function createBMD (dObj: DisplayObject): BitmapData // maak een nieuw BitmapData-object ter grootte van ons DisplayObject var bmd: BitmapData = nieuwe BitmapData (dObj.width, dObj.height, true, 0xFF000000); // teken het weergaveobject naar de bitmapgegevens bmd.draw (dObj); terugkeer bmd;
Bekijk wat deze functie doet. De eerste regel gebruikt de breedte en hoogte van de DisplayObject om een nieuw transparant BitmapData-object te maken van dezelfde grootte als het DisplayObject. Vervolgens tekent het DisplayObject naar de BitmapData. Uiteindelijk retourneert het de BitmapData aan de beller.
Hier vindt de feitelijke kleurscheiding plaats. Voeg deze functie toe aan uw klas:
persoonlijke functie createRGB (dObj: DisplayObject): Array var bmd: BitmapData = createBMD (dObj); // create bitmapData van het weergaveobject // maak een nieuw bitmap-gegevensobject voor elk kleurkanaal var r: BitmapData = nieuwe BitmapData (bmd.width, bmd.height, true, 0xFF000000); var g: BitmapData = nieuwe BitmapData (bmd.width, bmd.height, true, 0xFF000000); var b: BitmapData = nieuwe BitmapData (bmd.width, bmd.height, true, 0xFF000000); // kopieer de gegevens van elk kanaal naar de overeenkomstige bitmapgegevens r.copyChannel (bmd, bmd.rect, new Point (), BitmapDataChannel.RED, BitmapDataChannel.RED); g.copyChannel (bmd, bmd.rect, new Point (), BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); b.copyChannel (bmd, bmd.rect, new Point (), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE); // retourneer een array met de bitmapgegevens voor de 3 kleurkanalen return [r, g, b];
Deze functie accepteert ook een DisplayObject. Vervolgens geeft het dat door aan de createBMD () functie die we in de vorige stap hebben geschreven, die deze converteert naar BitmapData. Vervolgens maken we drie nieuwe transparante BitmapData-objecten; één voor elke kleur. We maken ze op exact dezelfde grootte als onze bron BitmapData (van het DisplayObject).
We gebruiken vervolgens BitmapData's copyChannel () methode om een enkel kleurkanaal te kopiëren van de bron BitmapData naar elk van de drie nieuwe BitmapData-objecten.
De laatste regel retourneert eenvoudigweg de drie nieuwe BitmapData-objecten die in een array zijn gewikkeld.
Nu dat we onze hebben createBMD en createRGB klassen die samenwerken, laten we ze gebruiken. Voeg dit toe als de eerste regel code in de constructorfunctie voor de RGBShift-klasse:
var rgbBMD: Array = createRGB (dObj);
Deze regel geeft het DisplayObject gewoon door aan de createRGB () functie. createRGB () gebruikt de createBMD () functie om het naar BitmapData om te zetten en scheidt het vervolgens in drie afzonderlijke BitmapData-objecten (één voor elk kanaal). Uiteindelijk retourneert het de array van die drie objecten naar onze lokale rgbBMD matrix. Heb je zin? Goed.
We hebben nu een array van drie BitmapData-objecten. We moeten van elk een bitmap maken om ze op het scherm weer te geven. Voeg dit toe voor loop naar de constructorfunctie van RGBShift net onder de laatste regel die we hebben toegevoegd:
Opmerking van de uitgever: Excuses voor het ongemak, maar dit specifieke stukje ActionScript geeft FireFox weer. Je kunt het hier gratis downloaden.
Het meeste is vrij eenvoudig. Laten we kijken.
Je zou dit effect kunnen maken zonder de container Sprite door de Bitmaps gewoon rechtstreeks aan het podium toe te voegen. Ik vind het leuk om ze in een container te wikkelen, omdat het het transformeren gemakkelijker maakt als je dingen doet als schaal en roteren.
Normaal gesproken transformeert het apparaat vanaf het beginpunt (0,0) van dat object wanneer u een schaal of rotatie op een object uitvoert. Dat is zelden wat ik wil laten gebeuren. Meestal wil ik dat de transformaties vanuit het midden van het object worden toegepast.
Merk op dat we in de laatste sectie de x en y van de Bitmaps instellen negatief de helft van de breedte en hoogte. Hierdoor wordt de Bitmap zo geplaatst dat het middelpunt zich op 0,0 in de Sprite-container bevindt. Als we transformaties uitvoeren op de Sprite-container, transformeert deze van 0,0 van de container, die nu het centrum van onze Bitmap is.
Het enige probleem is dat alleen de onderste hoek van onze Bitmap nu zichtbaar is, dus ik stel de container Sprite x en y in op de helft van de hoogte en breedte van de Bitmap om alles terug te krijgen op de juiste positie.
Hier is de RGBShift-klasse tot nu toe, voor het geval je onderweg bent verdwaald:
Opmerking van de uitgever: Ik nogmaals, je zult de AS hier opnieuw moeten downloaden. Excuses voor het ongemak.
Dus we hebben onze RGBShift-klasse, maar hoe gebruiken we deze? Begin met het maken van een nieuw Actionscript-bestand met de naam Main.as en voeg deze code toe:
pakket import flash.display.MovieClip; public class Main breidt MovieClip uit public function Main () var rgb = new RGBShift (titleScreen); // maak een nieuwe RGBShift vanuit de titleScreen removeChild (titleScreen); // verwijder het originele titelscherm van het podium // voeg het toe aan het podium addChild (rgb);
Hier maken we een nieuwe instantie van de RGBShift-klasse en geven deze de titelscherm MovieClip van het podium. We hebben die MovieClip niet langer nodig, dus we verwijderen hem uit het werkgebied en voegen in plaats daarvan de nieuwe instantie RGBShift toe.
Nu hoeven we alleen deze klasse te koppelen aan ons Flash-document. Ga terug naar Flash en stel de documentklasse in op 'Hoofd'.
U zou nu uw Flash-bestand (Controle -> Film testen) moeten kunnen testen zonder fouten of waarschuwingen te krijgen.
Hmm, dat ziet er niet helemaal goed uit?
Wat hier gebeurt is dat we de drie kleurkanalen op elkaar hebben gelaagd, maar ze combineren en mengen de kleuren niet, dus we zien alleen de bovenste laag (blauw). Laten we dat nu oplossen.
Om de kleurkanalen goed te laten blenden, moeten we hun BlendMode in SCREEN veranderen. We willen echter alleen de overvloeimodus van de tweede en derde laag wijzigen. We laten de eerste (onderste) laag normaal en mengen de andere twee lagen erin.
Voeg deze code toe aan de voor loop in de constructorfunctie van de RGBShift-klasse:
if (i> 0) // set SCREEN blend-modus voor de 2e en 3e afbeeldingen bmp.blendMode = BlendMode.SCREEN;
Hiermee wordt gecontroleerd of de huidige afbeelding niet de eerste afbeelding (0) is en wordt de eigenschap blendMode ingesteld op SCHERM.
Test uw film opnieuw en u zou iets moeten zien dat identiek is aan uw titelScreen MovieClip.
Ik weet wat je denkt; 'Dat was een hoop werk om dezelfde grafische weergave te maken die er al was.'
Maar nu bestaat de grafiek uit drie objecten die we individueel kunnen transformeren om onze vervorming te creëren. Dus stop met jammeren en laten we doorgaan ...
We gaan de Tweener-bibliotheek gebruiken om onze animatie te maken. Download het hier als je het nog niet hebt.
Om Tweener te gebruiken, plaatst u de hoofdmap 'caurina' in dezelfde map als uw Flash-bestand en voegt u deze importinstructie toe aan de bovenkant van de RGBShift-klasse:
import caurina.transitions.Tweener;
Ik gebruik dit randRange functioneer als een gemakkelijke manier om willekeurige gehele getallen binnen een bepaald bereik te genereren. Je zou deze functie gewoon aan de RGBShift-klasse kunnen toevoegen, maar ik gebruik deze functie zo vaak dat ik deze graag in een apart bestand bewaar, dus het is gemakkelijker om te delen tussen verschillende projecten.
Maak een nieuw Actionscript-bestand met de naam 'randRange.as' in dezelfde map als je hoofd Flash-bestand. Voeg deze code toe:
package // geeft een willekeurig getal tussen opgegeven bereik (inclusief) public function randRange (min: int, max: int): int var randomNum: int = Math.floor (Math.random () * (max - min + 1 )) + min; return randomNum;
Zoals u kunt zien is het slechts een enkele functie verpakt in een pakketverklaring. We kunnen deze functie nu gebruiken alsof het een deel van onze klas is.
(Voor meer informatie over hoe deze functie werkt, bekijk Carlos's Quick Tip.)
Hier gebeurt de magie. Voeg deze functie toe aan de RGBShift-klasse:
private function distort (img: Sprite): void Tweener.addTween (img, y: randRange (_centerY-3, _centerY + 3), // randomize y shift time: randRange (1,2) / 10, // randomize tijd alpha: randRange (8,10) / 10, // randomize alpha transition: "easeInOutSine", onComplete: distort, // when finish start the distortion again onCompleteParams: [img]);
We gaan dit uitvoeren vervalsen () functie op elk van onze kleurkanalen afzonderlijk om het vervormingseffect te creëren.
De functie accepteert een Sprite (een van onze kleurkanaalcontainers). Vervolgens start het een Tweener-animatie op het kanaal met een willekeurige Y-waarde (tussen -3 en 3) en een willekeurige tijdsduur (tussen 1 en 2 seconden). Dit zorgt ervoor dat elk kanaal met verschillende snelheden op en neer gaat.
Merk op dat ik de variabele _centerY hier opnieuw gebruik om de Y-waarde te compenseren. We tweenen ook naar een willekeurige alpha-waarde (tussen .8 en 1) om elk kanaal een beetje te laten flikkeren. Wanneer de tween is voltooid, gebruiken we de eigenschap onComplete om hetzelfde te bellen vervalsen () opnieuw functioneren. Met onCompleteParams sturen we het hetzelfde kleurkanaal Sprite. Dit zorgt ervoor dat de vervormingsfunctie steeds overloopt op elk van onze kleurkanalen.
Kijk, wat heb ik je gezegd ...? Magie!
Om deze distortion-loop te starten, moeten we deze eenmaal bellen op elk van onze kleurkanalen Sprites. Voeg deze regel toe aan het einde van de voor loop in de RGBShift constructorfunctie:
vervalsen (container); // start de bitmapvervorming
Je zou nu je film kunnen testen en het vervormingseffect in actie kunnen zien.
Persoonlijk vind ik de subtiele Y-shift die we hier hebben, maar je kunt veel gekke dingen doen met de vervorming nu we de kanalen afzonderlijk laten animeren.
Om met de vervorming te experimenteren, kunt u de eigenschappen en waarden in de Tweener-aanroep in de verdraaien functie. Raadpleeg de Tweener-documentatie voor een volledige lijst met tweenbare eigenschappen.
Hier is een voorbeeld van een aantal ernstige vervormingen die ik heb gemaakt door gewoon een paar extra eigenschappen aan de Tweener-oproep toe te voegen:
Bekijk de vervalsen () functie die het effect creëerde:
private function distort (img: Sprite): void Tweener.addTween (img, y: randRange (_centerY-3, _centerY + 3), // ranomize y shift x: randRange (_centerX-10, _centerX + 10), time : randRange (1,2) / 10, // randomize time scaleX: randRange (9,11) / 10, // randimize x scale alpha: randRange (5,10) / 10, // randomize alpha transition: "easeInOutSine" , onComplete: distort, // wanneer u klaar bent, start u de vervorming opnieuw opCompleteParams: [img]);
Je kunt hier stoppen als je wilt. De RGB-scheiding en vervorming zouden op dit punt moeten werken.
Om het CRT-effect te verbeteren, denk ik dat we een paar meer grafische elementen moeten toevoegen. In de volgende paar stappen zullen we scanlijnen toevoegen, een rollende zwarte balk, wat statische en een glanzende reflectie.
Maak een nieuwe MovieClip in het werkgebied met de naam 'lines'. Teken in de MovieClip een horizontale lijn van 1 pixel die de hele breedte van uw film beslaat. Zet de lijnkleur op zwart met 40% alpha.
Kopieer en plak nu deze regel steeds opnieuw en verplaats deze telkens met 2 pixels, totdat je lijnen hebt die de volledige hoogte van je film beslaan. Het gewenste effect is een regel van 1 pixel en vervolgens een pixel van 1 pixel voor de volgende regel.
Nu voegen we de rollende zwarte balk toe. Maak een nieuwe MovieClip met de naam 'balk'. Teken binnen een effen zwarte rechthoek over de hele breedte van je film. Maak het ongeveer 40 pixels hoog. Stel de kleurstijl van de MovieClip in op Alpha bij 30%.
Maak een nieuwe MovieClip genaamd 'animatingBar' en plaats jouw bar clip binnen. Maak een korte-bewegings-tween-animatie van de balk die van de bovenkant van je film naar de onderkant gaat. Deze animatie loopt door en geeft ons het rolling bar-effect.
Plaats de animatingBar-clip op het podium. Selecteer het en voeg een wazig filter toe. Ontkoppel de X- en Y-vervaginginstellingen en stel de vervaging Y in op 20 en vervaag X op 0.
Stel de overvloeimodus in op Overlay. Dit is vergelijkbaar met de schermmengmodus die we eerder hebben gebruikt, maar niet precies hetzelfde.
Maak een nieuw Photoshop-bestand van hetzelfde formaat als uw film. Vul de achtergrondlaag met neutraal grijs (# 808080). Kies Filter> Ruis> Ruis toevoegen ...
Stel het filter in op 100%, Gaussiaans, Monochroom.
Sla de afbeelding op als 'noise.jpg'. Als je geen Photoshop hebt, kun je mijn 'noise.jpg' uit het Bron-zipbestand halen.
Importeer de noise.jpg afbeelding in uw flash-bestand. Maak een nieuwe MovieClip met de naam 'ruis' en voeg de afbeelding eraan toe. Maak een nieuw keyframe op frame 2 (F6) en roteer de afbeelding 180 graden. Maak nog een keyframe op frame 3 en draai de afbeelding horizontaal om (Aanpassen> Transformeren> Horizontaal spiegelen). Maak een vierde keyframe op frame 4 en roteer de afbeelding opnieuw 180 graden. We hebben nu een animatie met 4 frames van flikkerende statische elektriciteit.
U kunt dit ruiseffect ook genereren met ActionScript, maar dat valt buiten het bestek van deze zelfstudie.
Maak een nieuwe MovieClip op het toneel met de naam 'shine'. Binnenin teken je een groot ovaal dat zich tot halverwege boven je film uitstrekt. Selecteer het bovenste gedeelte van het ovaal en verwijder het.
Verander de vulling in een lineair verloop en stel het zo in dat het van wit 20% alpha aan de bovenkant naar wit 5% alpha aan de onderkant mengt. Pak de bovenkant van de vorm en trek hem een beetje omhoog om hem een lichte buiging te geven.
Als u uw film nu test, ziet u geen van de nieuwe afbeeldingen die we zojuist hebben toegevoegd, omdat de RGB-lagen bovenop alles worden toegevoegd. Om dit op te lossen ga je naar de Hoofd class en verander deze regel:
addChild (RGB);
Hiernaar:
addChildAt (rgb, 0);
Dat voegt het RGBShift-object toe op het laagste niveau van de displaylijst, onder alle andere afbeeldingen.
Deze tutorial is bedoeld als een startpunt, niet als een definitieve oplossing. Nu dat je de RGB-kanalen hebt gescheiden en afzonderlijk kunt animeren, zijn er veel verschillende dingen die je met deze techniek kunt doen. Het effect zou er heel goed uitzien als het werd gecombineerd met de statische vervormingstechniek uit mijn eerdere zelfstudie.
Zoals altijd, plaats een reactie en laat me weten wat je ervan vindt. Succes!