Bouw een opvallend breakout-spel in Flash

In deze Premium-zelfstudie bouwen we een breakout-game; "Brick Breaker" vanuit het niets met Flash en AS3.


Stap 1: Kort overzicht

Met behulp van de Flash-tekengereedschappen maken we een goed uitziende grafische interface die wordt aangedreven door verschillende ActionScript 3-klassen.

De gebruiker kan een reeks niveaus spelen, je kunt eenvoudig zoveel niveaus toevoegen als je wilt!


Stap 2: Instellingen voor Flash-document

Open Flash en maak een 320 pixels breed, 480 pixels lang document. Stel de beeldsnelheid in op 24 fps.



Stap 3: Interface


Een kleurrijke, mooi ogende interface wordt weergegeven. Het bevat meerdere vormen, knoppen, bitmaps en meer.

Laten we meteen beginnen met het maken van deze GUI.


Stap 4: Hoofdscherm


Dit is het hoofdscherm of de weergave, het zal de eerste afbeelding zijn die in onze game verschijnt.


Stap 5: Achtergrond

Maak een rechthoek van 320 x 480 en vul deze met dit radiale verloop: # 3A9826, # 102A07.


We gaan het een beetje meer detail geven door een Photoshop-filter toe te voegen, als je geen Photoshop hebt, kun je proberen een leuk effect toe te voegen met behulp van de Flash-hulpmiddelen.

Open de afbeelding in Photoshop en ga naar Filters> Textuur> Patchwork, gebruik de volgende instellingen:


Je krijgt zoiets als dit:


Deze achtergrond staat op het podium, evenals de indicatoren voor peddel, bal en tekst. Converteer de achtergrond naar a Filmclip en noem het bg.


Stap 6: Titel

Selecteer het tekstgereedschap (T), selecteer een geschikt lettertype en schrijf de titel van je spel. Ik heb dit formaat gebruikt: Akashi, 55pt, # FFCC33.


Selecteer het tekstveld en gebruik het paneel Filters om een ​​slagschaduw toe te voegen:


Dupliceer de tekst (Cmd + D) en verplaats deze 3 px naar boven om hem wat reliëf te geven.


Converteer de afbeeldingen naar een Filmclip en noem het MenuScreen, vergeet niet om het te markeren Exporteren voor ActionScript doos. Je kunt dit uit het stadium verwijderen als je klaar bent, want het wordt gebeld met AS3.


Stap 7: Peddelen

Gebruik het Primitieve gereedschap rechthoek (R) om een ​​ronde rechthoek van 57x11.5px te maken, verander de hoekradius in 10 en pas dit verloop toe: # 4E4E4E, #BABABA, # B0B3BA.


Voeg een aantal detailregels toe met de Rectangle Tool, gebruik je eigen stijl!


Je kunt ook wat kleur toevoegen aan je paddle, hier is het eindresultaat van mij, de gebruikte kleur is: # CC0000.


Converteer de afbeeldingen naar een Filmclip en noem het peddelen.


Stap 8: Ball

Om de bal te maken, selecteer je de Oval Tool (O) en gebruik je deze om een ​​12x12px, #CCCCCC-cirkel te maken.


Dupliceer de cirkel (Cmd + D) verander de grootte in 10x10px en vul deze met dit radiale verloop: # 95D4FF, # 0099FF.


Knip als laatste de tweede cirkel doormidden en gebruik het gereedschap Selectie (V) om een ​​curve in de bodem te maken. Verander de kleur in een wit lineair verloop met alpha 60, 10.


Converteer de afbeeldingen naar een Filmclip en noem het bal.


Stap 9: Brick

Onze steen zal heel eenvoudig zijn.

Gebruik het gereedschap Rechthoek om een ​​rechthoek van 38x18px te maken en het volgende verloop toe te passen: # CC0000, # 8E0000, # FF5656.


Converteer de rechthoek naar een MovieClip en pas het schaduwfilter toe dat in de titeltekst wordt gebruikt om het een mooiere uitstraling te geven.

Converteer de afbeelding opnieuw naar a Filmclip en noem het Steen, vergeet niet om het te markeren Exporteren voor ActionScript doos.


Stap 10: Over het scherm

Het scherm Info toont de credits, het jaar en het copyright van het spel.

Het zal vrij eenvoudig zijn om te creëren omdat we al alle elementen erin hebben gebruikt.


Converteer de afbeeldingen naar een Filmclip en noem het AboutScreen, vergeet niet om het te markeren Exporteren voor ActionScript doos.


Stap 11: Spelscherm

Dit is het spelscherm, het zal vanaf het begin op het podium staan ​​en het bevat de peddel-, bal-, achtergrond- en tekstindicatoren. (We voegen de stenen toe met behulp van de code.)


De instantienamen zijn vrij eenvoudig en voor zichzelf verklarend: peddel, bal, bg, score TF, livesTF en levelTF.


Stap 12: Fonts insluiten

Als u het aangepaste lettertype dynamisch wilt gebruiken, moeten we dit in de toepassing insluiten.

Selecteer een dynamisch tekstveld en klik op de insluiten? knop in de Eigenschappen paneel.


Selecteer / voeg alle benodigde tekens toe en klik op OK.


Stap 13: Waarschuwingsscherm

Dit scherm verschijnt als het spel is beslist; of je wint, verliest of je bereikt het spel (alle levels winnen of alle levens verliezen).

In deze weergave worden twee dynamische tekstvelden gebruikt, deze geven de huidige spelstatus plus een kort bericht weer. De TextFields zijn benoemd titleTF en msgTF.


Converteer de afbeeldingen naar een Filmclip en markeer de Exporteren voor ActionScript box, stel de klassenaam in op AlertScreen.

Hiermee beëindigt u het grafische gedeelte, laat het ActionScript beginnen!


Stap 14: Tween Nano


We gebruiken een andere tween-engine dan de standaard in de flash-modus, dit zal de prestaties verbeteren en gemakkelijker in gebruik zijn.

Je kunt Tween Nano downloaden van de officiële website.


Stap 15: Nieuwe ActionScript-klasse

Maak een nieuwe ActionScript 3.0-klasse (Cmd + N) en sla deze op als Main.as in je klasmap.



Stap 16: klassenstructuur

Maak uw standaard klassenstructuur om te beginnen met het schrijven van uw code.

 pakket import flash.display.Sprite; public class Hoofd breidt uit openbare functie Main (): void // constructor code

Stap 17: Vereiste klassen

Dit zijn de klassen die we moeten importeren voor onze klas om te werken, de importeren richtlijn maakt extern gedefinieerde klassen en pakketten beschikbaar voor uw code.

 import flash.display.Sprite; import flash.ui.Mouse; import flash.events.MouseEvent; import flash.events.KeyboardEvent; import flash.events.Event; import com.greensock.TweenNano; import com.greensock.easing.Circ;

Stap 18: Variabelen en constanten

Dit zijn de variabelen en constanten die we zullen gebruiken, lees de opmerkingen in de code om meer over hen te ontdekken.

 private const BRICK_W: int = 39; // brick's width private const BRICK_H: int = 19; // brick's height private const OFFSET: int = 6; // Een verspringing die wordt gebruikt om de stenen te conten- seren private const W_LEN: int = 8; // de lengte van de niveaus, alleen 8 horizontale stenen moeten worden gemaakt op het podium private const SCORE_CONST: int = 100; // het bedrag dat aan de score moet worden toegevoegd wanneer een baksteen geraakt wordt private var bricks: Vector. = nieuwe Vector.(); // slaat alle stenen op private var xSpeed: int = 5; privévar ySpeed: int = -5; privé var xDir: int = 1; // x richting private var yDir: int = 1; private var gameEvent: String = "; // slaat events op zoals win, lose, gameover private var currentLevel: int = 0; private var menuScreen: MenuScreen; // een instantie van het menuscherm private var aboutScreen: AboutScreen; private var alertScreen: AlertScreen; private var lives: int = 3; private var-niveaus: Array = []; // slaat de niveaus op

Stap 19: Niveaus

Al onze niveaus worden opgeslagen in multidimensionale arrayss.

Dit zijn arrays met arrays; je kunt ze in een enkele regel schrijven, maar als je ze uitlijnt, kun je de vorm zien die het niveau zal aannemen.

 private const LEVEL_1: Array = [[0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,0,0, 1,1,0,0,0], [0,0,0,1,1,0,0,0], [0,1,1,1,1,1,1,0], [0, 1,1,1,1,1,1,0], [0,0,0,1,1,0,0,0], [0,0,0,1,1,0,0,0] , [0,0,0,0,0,0,0,0],]; // dit vormt een + teken! private const LEVEL_2: Array = [[0,0,0,0,0,0,0,0], [0,0,0,1,1,0,0,0], [0,0,1, 0,0,1,0,0], [0,0,0,0,0,1,0,0], [0,0,0,0,1,0,0,0], [0, 0,0,1,0,0,0,0], [0,0,1,0,0,0,0,0], [0,0,1,1,1,1,0,0] ,]; // dit vormt een nummer 2!

In deze niveaus de 1s vertegenwoordigen de ruimte in de fase waarin een steen zal worden geplaatst, en de 0s zijn gewoon lege ruimte. Deze niveaus worden later gelezen door een functie die de stenen op het podium plaatst. U kunt zoveel niveaus toevoegen als u wilt met deze klasse!


Stap 20: Constructor Code

De constructor is een functie die wordt uitgevoerd wanneer een object wordt gemaakt op basis van een klasse; deze code is de eerste die wordt uitgevoerd wanneer u een exemplaar van een object maakt (of wordt uitgevoerd wanneer het spel wordt geladen, in het geval van een documentklasse).

Het roept de nodige functies op om het spel te starten. Bekijk deze functies in de volgende stappen.

 openbare laatste functie Main (): void / * Voeg niveaus toe * / levels.push (LEVEL_1, LEVEL_2); // we voegen de niveaus toe aan de array om te weten hoeveel ze zijn / * Menu Scherm, Knoppen Luisteraars * / menuScreen = new MenuScreen (); addChild (menuScreen); menuScreen.startB.addEventListener (MouseEvent.MOUSE_UP, tweenMS); menuScreen.aboutB.addEventListener (MouseEvent.MOUSE_UP, tweenMS); 

Stap 21: Menuscherm & Info Animatie bekijken

De volgende regels behandelen de knoppen van het menuscherm en tween het menu of de weergave About, afhankelijk van de ingedrukte knop.

 privé-finale functie tweenMS (e: MouseEvent): void if (e.target.name == 'startB') // als op de startknop wordt geklikt TweenNano.to (menuScreen, 0.3, y: -menuScreen.height, ease : Circ, onComplete: init); // tween menuscherm anders // als er op de knop wordt geklikt aboutScreen = new AboutScreen (); // add about screen addChild (aboutScreen); TweenNano.from (aboutScreen, 0.3, x: stage.stageWidth, ease: Circ); // tween over scherm over Screen.addEventListener (MouseEvent.MOUSE_UP, hideAbout); // voeg een muislist toe om het te verwijderen / * Verwijdert Over weergave * / private laatste functie hideOver (e: MouseEvent): void TweenNano.to (aboutScreen, 0.3, x: stage.stageWidth, ease: Circ, onComplete : function rmv (): void aboutScreen.removeEventListener (MouseEvent.MOUSE_UP, hideOver); removeChild (aboutScreen);); 

Stap 22: Init-functie

Deze functie voert de nodige bewerkingen uit om het spel te starten, lees de opmerkingen in de code om er meer over te weten.

 private finale functie init (): void / * Destroy Menu Screen * / menuScreen.startB.removeEventListener (MouseEvent.MOUSE_UP, tweenMS); menuScreen.aboutB.removeEventListener (MouseEvent.MOUSE_UP, tweenMS); removeChild (menuScreen); menuScreen = null; / * Verberg Cursor * / Mouse.hide (); / * Build Level Bricks * / buildLevel (LEVEL_1); / * Start Listener * / bg.addEventListener (MouseEvent.MOUSE_UP, startGame); 

Stap 23: beweeg peddel

De Paddle wordt muisgestuurd en volgt de x-positie van de muis .

 private laatste functie movePaddle (e: MouseEvent): void / * Follow Mouse * / paddle.x = mouseX; 

Stap 24: Padding Border Collision

Om te voorkomen dat de paddle het podium verlaat, creëren we onzichtbare grenzen aan de zijkanten van het scherm.

 / * Volg Mouse * / paddle.x = mouseX; / * Grenzen * / if ((paddle.x - paddle.width / 2) < 0)  paddle.x = paddle.width / 2;  else if((paddle.x + paddle.width / 2) > stage.stageWidth) paddle.x = stage.stageWidth - paddle.width / 2; 

Stap 25: Build Level-functie

De niveaus zullen door deze functie worden gebouwd.

Het gebruikt een parameter om het te bouwen niveau te verkrijgen, berekent de grootte en voert een geneste for-loop uit, met één lus voor de hoogte en één voor de breedte. Vervolgens wordt een nieuwe Brick-instantie gemaakt die wordt geplaatst op basis van de breedte, hoogte en het nummer dat overeenkomt met ik en j.

Ten slotte wordt de steen toegevoegd aan de bakstenen vector om toegang te krijgen buiten deze functie.

 private eindfunctie buildLevel (level: Array): void / * Niveau lengte, hoogte * / var len: int = level.length; for (var i: int = 0; i < len; i++)  for(var j:int = 0; j < W_LEN; j++)  if(level[i][j] == 1)  var brick:Brick = new Brick(); brick.x = OFFSET + (BRICK_W * j); brick.y = BRICK_H * i; addChild(brick); bricks.push(brick);    

Stap 26: Spelluisteraars

Met deze functie kunt u de muis toevoegen of verwijderen en framelinkluisteraars openen. Het gebruikt een parameter om te bepalen of de luisteraars moeten worden toegevoegd of verwijderd: standaard is toevoegen.

 private slotfunctie gameListeners (actie: String = 'add'): void if (action == 'add') stage.addEventListener (MouseEvent.MOUSE_MOVE, movePaddle); stage.addEventListener (Event.ENTER_FRAME, update);  else stage.removeEventListener (MouseEvent.MOUSE_MOVE, movePaddle); stage.removeEventListener (Event.ENTER_FRAME, update); 

Stap 27: start de spelfunctie

De volgende code roept de gameListeners () functie om het spel te starten.

 private finale functie startGame (e: KeyboardEvent): void bg.removeEventListener (MouseEvent.MOUSE_UP, startGame); gameListeners (); 

Stap 28: Balverplaatsing

De balsnelheid wordt bepaald door de xSpeed en ySpeed variabelen, wanneer de bijwerken functie wordt uitgevoerd, de bal begint te bewegen met behulp van deze waarden per frame.

 update van privé-finale functie (e: Event): void / * Ball Movement * / ball.x + = xSpeed; ball.y + = ySpeed;

Stap 29: Muurbotsing

Deze code controleert op botsingen tussen de bal en de muren.

 / * Muurbotsing * / if (ball.x < 0)ball.x = ball.x + 3;xSpeed = -xSpeed;;//Left if((ball.x + ball.width) > stage.stageWidth) ball.x = ball.x - 3; xSpeed ​​= -xSpeed;; // Right if (ball.y < 0)ySpeed = -ySpeed;;//Up

Stap 30: Game-evenement verliezen

Een if-statement wordt gebruikt om te controleren wanneer de peddel de bal mist. Als dat zo is, verliest de speler een leven.

 if (ball.y + ball.height> paddle.y + paddle.height) alert ('You Lose', 'Play Again?'); gameEvent = 'lose'; lives -; livesTF.text = String (lives ); // down / verliezen

Stap 31: Paddle-ball botsingen

Wanneer de bal de peddel raakt, wordt de ySpeed ​​ingesteld op negatief om de bal omhoog te laten gaan. We controleren ook in welke kant van de peddel de bal heeft geslagen om de kant te kiezen waar hij naartoe zal bewegen.

 / * Paddle Collision, controleer welke kant van de peddel de bal raakt * / if (paddle.hitTestObject (ball) && (ball.x + ball.width / 2) < paddle.x)  ySpeed = -5; xSpeed = -5; //left  else if(paddle.hitTestObject(ball) && (ball.x + ball.width / 2) >= paddle.x) ySpeed ​​= -5; xSpeed ​​= 5; // rechts

Stap 32: Brick Collisions

We gebruiken een voor en hitTest om botsingen met stenen te controleren, wanneer de bal een steen raakt, wordt dezelfde techniek gebruikt in de paddle gebruikt om de kant te bepalen die de bal zal volgen.

 / * Bricks Collision * / for (var i: int = 0; i < bricks.length; i++)  if(ball.hitTestObject(bricks[i]))  /* Check the which side of the brick the ball hits, left, right */ if((ball.x + ball.width / 2) < (bricks[i].x + bricks[i].width / 2))  xSpeed = -5;  else if((ball.x + ball.width / 2) >= (bricks [i] .x + bricks [i] .width / 2)) xSpeed ​​= 5; 

Stap 33: Verander de richting van de bal en verwijder de steen

De volgende code verandert de Y-richting van de bal en verwijdert de steen van het werkvlak en de vector.

 / * Ball y-richting wijzigen * / ySpeed ​​= -ySpeed; removeChild (stenen [i]); bricks.splice (i, 1);

Als je wilt, kun je deze logica wijzigen, zodat de y-snelheid van de bal alleen wordt omgekeerd als deze de boven- of onderkant van een steen raakt, en niet als deze de zijkanten raakt. Probeer het en zie wat je denkt.


Stap 34: Score toevoegen en Win selecteren

Elke baksteenhit voegt 100 toe aan de score, de score wordt genomen uit de scoreconstante en toegevoegd aan de huidige score met int en Draad functies. Deze code controleert ook of er geen stenen meer in de Vector staan ​​en geeft zo nodig een waarschuwing weer.

 / * Score ++ * / scoreTF.text = String (int (scoreTF.text) + SCORE_CONST);  / * Controleer of alle stenen zijn vernietigd * / if (bricks.length < 1)  alert('You Win!', 'Next Level ?'); gameEvent = 'win';  

Stap 35: Waarschuwingsscherm

Het waarschuwingsscherm toont de spelersinformatie over de status van het spel, het wordt getoond wanneer een spelgebeurtenis wordt bereikt, zoals het verliezen van een leven of het voltooien van een niveau.

Twee parameters worden gebruikt in deze functie:

  • t: De meldingstitel
  • m: Een kort bericht
 privé-eindsignaal (t: String, m: String): void gameListeners ('remove'); Mouse.show (); alertScreen = nieuw AlertScreen (); addChild (alertScreen); TweenNano.from (alertScreen.box, 0.3, scaleX: 0.5, scaleY: 0.5, ease: Circ); alertScreen.box.titleTF.text = t; alertScreen.box.msgTF.text = m; alertScreen.box.boxB.addEventListener (MouseEvent.MOUSE_UP, restart); 

Stap 36: Herstartfunctie

De volgende functie controleert de spelstatus (winnen, verliezen, afgewerkt) en voert een actie uit volgens deze.

 privé laatste functie opnieuw opstarten (e: MouseEvent): void if (gameEvent == 'win' && levels.length> currentLevel + 1) // als het niveau duidelijk is maar er meer niveaus over zijn currentLevel ++; changeLevel (niveaus [currentLevel]); // next level levelTF.text = 'Level' + String (currentLevel + 1);  else if (gameEvent == 'win' && levels.length <= currentLevel+1) //if level is clear and no more levels are available  alertScreen.box.boxB.removeEventListener(MouseEvent.MOUSE_UP, restart); removeChild(alertScreen); alertScreen = null; alert('Game Over', 'Congratulations!'); gameEvent = 'finished';  else if(gameEvent == 'lose' && lives > 0) // als niveau mislukt maar levens> 0 changeLevel (niveaus [currentLevel]); // zelfde niveau else if (gameEvent == 'lose' && lives <= 0) //if level failed and no more lives left  alertScreen.box.boxB.removeEventListener(MouseEvent.MOUSE_UP, restart); removeChild(alertScreen); alertScreen = null; alert('Game Over', 'Try Again!'); gameEvent = 'finished';  else if(gameEvent == 'finished') //reached when no more lives or levels are available  /* Add menu screen */ menuScreen = new MenuScreen(); addChild(menuScreen); menuScreen.startB.addEventListener(MouseEvent.MOUSE_UP, tweenMS); menuScreen.aboutB.addEventListener(MouseEvent.MOUSE_UP, tweenMS); TweenNano.from(menuScreen, 0.3, y: -menuScreen.height, ease: Circ); /* Reset vars */ currentLevel = 0; lives = 3; livesTF.text = String(lives); scoreTF.text = '0'; levelTF.text = 'Level ' + String(currentLevel + 1); xSpeed = 5; ySpeed = -5; clearLevel();  

Stap 38: Verander het niveau

Deze functie verandert in het niveau geschreven in de parameter.

 private laatste functie changeLevel (niveau: Array): void / * Clear * / clearLevel (); / * Bakstenen opnieuw tekenen * / buildLevel (niveau); / * Start * / Mouse.hide (); bg.addEventListener (MouseEvent.MOUSE_UP, startGame); 

Stap 39: Helder niveau

Een functie om de resterende stenen en waarschuwingen van het podium te wissen. Het zal ook de positie van de peddel en de bal resetten.

 private final-functie clearLevel (): void / * Alarmscherm verwijderen * / alertScreen.box.boxB.removeEventListener (MouseEvent.MOUSE_UP, restart); removeChild (alertScreen); alertScreen = null; / * Clear Level Bricks * / var bricksLen: int = bricks.length; for (var i: int = 0; i < bricksLen; i++)  removeChild(bricks[i]);  bricks.length = 0; /* Reset Ball and Paddle position */ ball.x = (stage.stageWidth / 2) - (ball.width / 2); ball.y = (paddle.y - paddle.height) - (ball.height / 2) -2; paddle.x = stage.stageWidth / 2; 

Stap 40: Stel hoofdklasse in


We maken in deze tutorial gebruik van de documentklasse, als je niet weet hoe je het moet gebruiken of een beetje in de war bent, lees dan deze QuickTip.


Conclusie

Het eindresultaat is een aanpasbaar en vermakelijk spel, probeer je eigen afbeeldingen en niveaus toe te voegen!

Ik hoop dat je deze Active Premium-zelfstudie leuk vond, bedankt voor het lezen!