Et eksempel fra HTX 2. år

Eksamensprojekt om Atari Breakout | Programmering C

Brug materialet til at undersøge opbygning, metode og faglige valg.

Programmering C 23 sider

Lær af eksemplet på 15 minutter

Læs med de tre spørgsmål herunder, og skriv et kort svar på hvert, gerne med et sidetal. Så har du noget konkret at tage med over i din egen opgave.

  1. 4 min

    Find problemformuleringen eller opgavens spørgsmål. Står svaret i konklusionen?

  2. 4 min

    Find et sted, hvor opgaven bruger en kilde eller et eksempel. Står der, hvor det kommer fra?

  3. 4 min

    Find et afsnit, der vurderer eller diskuterer. Hvad gør det anderledes end et afsnit, der forklarer?

  4. 3 min

    Din egen opgave: Hvad er det ene spørgsmål, din egen opgave svarer på, og står svaret i din konklusion?

Skal du selv skrive en opgave? Metoden står her: Akademisk opgaveskrivning

Om opgaven

Ophavet er ikke dokumenteret for denne post. Katalogoplysninger: HTX 2. år, Programmering C, 23 sider. Brug materialet til at se, hvordan teksten er bygget op, og hvilke faglige valg der er truffet.

Hele opgavens tekst

Se originaldokumentet

Læs teksten direkte her på siden. Figurer og den præcise opsætning af tabeller og formler finder du i originaldokumentet.

Gå til en side

Side 1

EKSAMENSPROJEKT

Programmering C

Thien An Tran 14xad / 2.D

Maj 2016

Side 2

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 1 af 22

Indhold

Indledning .......................................................................................................................................................... 1 Problemformulering .......................................................................................................................................... 1 Funktionsbeskrivelse og abstract ...................................................................................................................... 2 Dokumentation af selve programmet ............................................................................................................... 2 Overordnet .................................................................................................................................................... 2 Brikker............................................................................................................................................................ 3 Banebyggeren ................................................................................................................................................ 4 Bolden ............................................................................................................................................................ 5 Pladen ............................................................................................................................................................ 6 Kollisioner ...................................................................................................................................................... 6 Kollision mellem plade og bold ................................................................................................................. 6 Kollision mellem bold og brik .................................................................................................................... 7 Power-ups .......................................................................................................................................................... 8 Test af programmet ........................................................................................................................................... 9 Testkodning ................................................................................................................................................... 9 Selve testningen ............................................................................................................................................ 9 Konklusion ....................................................................................................................................................... 10 Bilag ................................................................................................................................................................. 10 Indledning

Denne journal handler om mit eksamensprojekt i Programmering C. Teamet for mit projekt er computerspil. Jeg har derfor valgt at lave en udgave af det klassiske spil, Atari Breakout. Ved at læse denne journal får du en indsigt i, hvordan spillet er opbygget, og hvad tankerne bag de forskellige elementer i spillet er.

Problemformulering

Mit valgte tema er computerspil. Til dette projekt vil jeg lavet et spil, der er baseret på det klassiske Atari Breakout. Til dette skal jeg finde ud af, hvordan spillet i hovedtræk fungerer, så jeg selv kan lave spillet. Jeg skal finde ud af, hvordan jeg kan simulere en bold, som bliver sendt rundt i en bane. Til dette skal jeg se på noget med vinkler. Jeg skal også finde ud af at simulere brikker, der forsvinder med kollision af bolden.

Formålet med projektet er, at jeg koder mig frem til at spilbart spil.

Side 3

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 2 af 22

Funktionsbeskrivelse og abstract

Startskærmen kan ses på billedet til højre.

Skærmstørrelsen for spillet er 800x600 pixels. Til spillet er der en menulinje øverst, som er 40 pixels bred. Den oplyser det level, som du er i, dine point og dine liv. Der er desuden en restart-knap, hvis man har brug for at starte forfra. Det er også et spørgsmålstegn, du kan trykke på, hvis du vil have at vide, hvordan man spiller spillet.

Til at styre spillet bruger man blot tre taster. A-tasten for at dreje til venstre, D-tasten for at dreje til højre og mellemrumstasten for resten. Oven i dette er der flere andre taster, som har funktioner, der er ment til at teste spillet. Jeg har valgt at lade nogle af test-funktionerne blive, så de kan fungere som en slags snydekoder.

Spillet går ud på, at du har en bold, som du sender rundt ved hjælp af en plade, som kun kan bevæge sig til højre og venstre. Du må få bolden til at ramme alle kanterne undtaget den nederste kant. Hvis den rammer den nederste kant, har du mistet et liv. Hvis du ikke har flere liv, har du tabt spillet. Det gælder om at få bolden til at kollidere med brikkerne i spillet, så de forsvinder. Når der ikke er flere brikker tilbage, kommer du til næste level.

Pladen er opbygget på sådan en måde, at vinklen af bolden bliver forskellige afhængig af, hvor bolden rammer på pladen. Til at gøre spillet sjovere, er der power-ups, der både kan gøre spillet lettere eller sværere. De forskellige power-ups er forklaret på billedet til højre.

Spillet består af seks levels, som du skal gennemføre for at vinde spillet. Kort sagt gælder det om at fjerne alle brikker, før du mister alle dine liv.

Dokumentation af selve programmet

Overordnet

Jeg vil nedenfor vise et flowchart, der i overordnede træk viser, hvordan mit spil fungerer:

Dette er en forenklet udgave af spillet.

Jeg har kun valgt at tage de vigtigste

Side 4

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 3 af 22 led ind i dette flowchart – jeg har eksempelvis undladt power-ups.

I teorien starter man i det gule felt og slutter i det grønne felt. Ellers slukker man spillet, hvis man har tabt og ikke gider at spille det længere.

Faktisk kan man genstarte spillet når som helst. Det er dog mest normalt, at man genstarter spillet, når man har tabt. Derfor er den placeret, som den er. Man kan eventuelt også genstarte, hvis man vil spille igen, efter man har vundet.

Til programmet har jeg anvendt en klasse (class), der gør det muligt for mig at lave flere af de samme objekter, uden at det kommer til at fylde meget tekstmæssigt – jeg laver en array-liste med ens objekter. Ved hjælp af forskellige koder kan jeg danne og fjerne ens objekter. Det praktiske er også, at de forskellige variabler i klassen kan bruges til alle objekterne, der er en del af den.

Når jeg anvender array-lister med objekter, skal jeg lave en for-struktur om al den kode, der har noget med objektet af gøre. På en måde sørger programmet for, at alle ens objekter bliver påvirket. En undtagelse er, ved den kode, hvor duplikater af objektet bliver skabt. Et eksempel på dette ses under:

Brikker

Til brikkerne i spillet har jeg lavet mine egne tegninger, som jeg uploader til programmet:

Side 5

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 4 af 22

Billederne er uploadet i void setup, da de kun behøves at blive indlæst én gang. Når brikkerne tegnes, får de forskellige farver afhængigt af de værdier, som int-variablen brick.colour får. Til højre på billeden over, kan man se, at værdien af brick.colour afgør, hvilket billede der bliver brugt ved hjælp af en If-else-sætning.

Billede i midten bliver uddybet i næste afsnit.

Banebyggeren

I de forskellige levels er brikkerne sat op på forskellige måder. Hver brik har sit eget koordinat. Jeg har derfor lavet loops, så jeg slipper for at give hvert enkelte brik sin eget koordinat. Forneden kan du se eksempler på banernes opbygning:

Mine loops består af if-sætninger. På grund af at jeg anvender netop if-sætninger, får jeg den effekt, at alle brikker ikke dannes i samme frame, men at de dannes én efter en. Det er modsat et for-loop.

Level 1 og level 5 har brikker, som har koordinater, der er dannet ved hjælp af float-variablerne ’i’ og ’j’, der fungerer som henholdsvis x- og y-koordinater. I disse baner tegner programmet række efter række. Hver gang en brik bliver tegnet, bliver ’i’ større, indtil den er nået til den satte grænse – den har tegnet en række.

Derefter bliver ’i’ nulstillet, og ’j’ bliver større – næste række bliver tegnet. Når ’j’ når til en bestemt værdi, som jeg selv har sat, er loopet færdigt, og banen er klar til at blive spillet.

Level 3 foregår efter et andet princip. Her bruger jeg et loop, hvor brikkerne bliver placeret tilfældigt. Med variablen ’e’, sørger jeg for, at der bliver dannet 70 brikker. Jeg bruger random()-funktionen til at frembringe tilfældige tal, som brikkernes koordinaterne får. Tallene i parentesen bestemmer intervallet for værdierne – fra 0 til det indtastede. Normalt frembringer funktionen en værdi med decimaltal. Når jeg bruger funktionen til at bestemme farve, skal jeg anvende heltal. Ved at skrive (int) foran en random-funktion tilpasser man funktionen til en int-værdi, som består af heltal (datatypen skal passe for at være kompatibel). I banen får jeg desuden brikkerne til at bevæge sig.

I level 5 giver jeg brikkerne en cirkulær bevægelse ved hjælp af en if-sætning. Jeg udnytter bricks.size() til at bestemme, hvornår banen er færdig med at blive tegnet. Til den cirkulære bevægelse anvender jeg cosinus-og sinus-funktionen.

Side 6

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 5 af 22

Bolden

Bolden i spillet er et billede, som jeg selv har tegnet. På trods af at bolden er rundt, har jeg defineret bolden som et kvadrat. Det gør, at kollisionskoden kan skrives mere simplet. Jeg kommer ind på dette senere.

Boldens bevægelse bliver styret ved hjælp af to funktioner, cosinus- og sinusfunktionen. De har den egenskab, at de er periodiske funktioner, der er udledt fra enhedscirklen. Ud fra en vinkel, som ball.angle har, bliver retningen bestemt.

Bevægelsen af bolden er omkranset i den gule boks i ovenstående billede.

Cosinus angiver, hvor meget bolden bevæger sig i x-aksens retning, mens sinus angiver y-aksens retning, når farten er ’1 pixel pr. frame’. Når dette ganges med ball.speed, kan jeg give den ønskede fart til bolden. Programmeringssproget definerer vinkler i radianer. Jeg skriver en vinkel ud fra divisioner med tau, som er det dobbelte af pi. Der står et minustegn foran sinus, da programmeringssproget definerer koordinatsystemet anderledes. Den positive retning for y-aksen er modsat i forhold til traditionelle koordinatsystemet.

Derfor jeg har sat et minus, selvom det egentlig ikke gør den store forskel. Det er dog praktisk, hvis det passer med den positive omløbsretning.

Da boldens bevægelse er omkranset af banen, sørger jeg for, at boldens vinkel ændres, når den rammer kanterne. Jeg prøver at lave drejningen virkelighedstro, som hvis bolden var på en plan bane. Hvis if-sætningerne bliver sande (bolden rører kanten), ændres vinklen. Hvordan, jeg er kommet frem til den nye vinkel, er vist nedenunder:

Dette er kun eksempler. Med et matematisk bevis kan man bevise, at den nye vinkel altid kan findes med disse formler.

Side 7

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 6 af 22

Pladen

Pladen i spillet, som skal styre boldens bevægelse, er defineret med rect(). Dvs. at det er en rektangel.

Pladen er ikke i en array-liste i forhold til de andre objekter, da jeg kun har brug for én plade.

Jeg får pladen til at bevæge sig ved hjælp af booleans og if-sætninger. Jeg benytter mig også af andre voids, som keyPressed og keyReleased. De bliver kun aktiveret, henholdsvis når man holder en tast nede, og når man slipper en tast. Så længe man holder ’a’ nede, bevæger man sig til venstre. Med ’d’ er det til højre.

Kollisioner

I mit spil har jeg forskellige former for kollisioner. Fælles for alle de kollisioner er, at der er overlap af figurerne ved en kollision. Alle mine objekter, der kolliderer, er defineret som rektangler, da det er lettere at have med at gøre. Med distancefunktioner for x-retningen og y-retningen og figurernes længde og bredde kan jeg afgøre, om der er overlap eller ej. I de to kommende underafsnit er måden til at se, om der er overlap vist.

Kollision mellem plade og bold

Det i den første if-sætning er sand, hvis der er overlap mellem bolden og pladen. Det sker, hvis x-distancen mellem centrene er mindre end halvdelen af boldens og pladens bredde. Det samme gælder for y-distancen, hvor der bare er højden i stedet for. Dette viser, at det er lettere at definere bolden som et rektangel.

Det er hensigtsmæssigt, at der bliver sørget for, at objekternes koordinater er centrerede, da det ellers vil være mere omfattende.

For at de samme vinkler ikke går igen, som når bolden rammer væggene, har jeg gjort, så vinklen, der kommer efter kollisionen, er afhængig af boldens afstand til centrum af pladen. Jeg har gjort dette ved hjælp af en skalleringsfunktion, så forholdet kan omsættes til vinkelforhold. Hvis bolden lander lige på

midten af pladen, bliver vinklen Tau/4, som er lige op. Med kollisionen får bolden en vinkel i intervallet

Side 8

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 7 af 22

[1/12 Tau;5/12 Tau]. Jeg lader ikke vinklen svinge mere end dette, da man kan risikere, at bolden får en
vinkel, der er tæt på 0 eller Tau/2, hvilket gør at bolden nærmest ikke får en opdrift.

Variablen ’float d’ er i øvrigt en lokal variabel. En lokal variabel er en variabel, der kun kan blive nået, i den tuborgklamme ({}), som den er omgivet af

Kollision mellem bold og brik

Den første if-sætning er efter samme princip som ved boldens kollision med pladen. Vinklen efter sammenstødet bliver dog afgjort på en anden måde. Hvis bolden ramte bolden oppefra elle nedefra, skal den reagere, som hvis den ramte en vandret væg. Hvis bolden ramte siderne, skal den reagere, som hvis den ramte en lodret væg.

Jeg bestemmer den nye vinklen ved hjælp af en udvidet if-else-sætning. Hvis boldens x-koordinat er inden for brikkens bredde, har jeg defineret, at den rammer over- eller undersiden.

Hvis boldens y-koordinat er inden for brikkens højde, har jeg defineret, at den rammer en af siderne. Det kan også hænde, at ingen af disse statements er sande. I dette tilfælde skal jeg afgøre, hvordan bolden bør reagere. Billedet til højre illustrerer hvordan jeg har skrevet de to sidste statements.

Ved if-else-sætningerne er der tilføjet noget, der hedder extra.width og extra.height. Det har jeg tilføjet for at forhindre dobbelt-vinkelskift, når bolden rammer to brikker på samme tid, hvor den rammer enten lodret eller vandret på dem begge. Når det sker, fortsætter bolden i samme retning, som om der ikke har været en kollision. Det gør ikke noget, hvis den på samme tid rammer vandret på den ene og lodret på den anden, da det ikke neutraliserer noget.

Side 9

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 8 af 22

Power-ups

Ligesom det klassiske Atari Breakout har denne udgave også power-ups. Der er en beskrivelse af dem i afsnittet om funktionsbeskrivelsen og i noten, Power-ups, i afleveringsmappen (den findes også i bilaget).

Koden til de forskellige power-ups kan ses foroven. De forskellige power-ups hører ind under samme array-liste. Dog er de meget forskellige i forhold til, hvad de gør. Det er int-variablen powerUp.colour, der giver de forskellige power-ups deres karakteristiske effekt.

Det er hver gang, der bliver fjernet en brik, at der er en mulighed, at der kommer en power-up. Jeg anvender random-funktionen, som jeg laver om til en int-værdi, så datatypen er kompatibel med powerUp.colour. Sandsynlighederne for de forskellige power-ups er beskrevet i noten. Kollisionen med power-ups er ligesom med de andre kollisioner, der er beskrevet i kollisionsafsnittet.

Ved power-up nr. 5, hvor der bliver dannet seks bolde, har jeg anvendt et for-loop. En fordel ved et for-loop i forhold til en if-loop er, at det sker i én frame.

Varigheden af det forskellige power-ups er varierende afhængig af typen. Nogle varer ved gennem hele banen, mens andre forsvinder efter noget tid. Hvis du ønsker mere viden om dem, kan du finde den i kodningen.

Side 10

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 9 af 22

Test af programmet

Testkodning

Til at teste spillet, har jeg lagt kode ind, der gør det lettere for mig at teste spillet. Eksempelvis har jeg gjort sådan, at bolden kan fjernstyres, hvis jeg trykker på spacebar og klikker med musen. Det har gjort det markant lettere at teste boldens kollision med diverse genstande, da det kan være svært at styre bolden med pladen. Hvis jeg trykker på ’p’ og klikker med musen, går jeg til næste level. Det er praktisk, hvis jeg hurtigt har brug for at springe til næste level. Jeg har også gjort, at tasterne 1, 2, 3 og 4 skaber power-ups fra bolden, når jeg trykker på dem. På den måde kan jeg teste forskellige kombinationer for at se, om der er uregelmæssigheder, når de kombineres. De forskellige powerups, som tasterne fremkalder, kan let byttes ud med andre. Jeg har senere valgt at lade testkoderne blive, da jeg synes, de kan fungere som snydekoder.

Selve testningen

Jeg har testet spillet på to forskellige måder. Først har jeg spillet, hvor jeg har anvendt testkodningen.

Senere har jeg spillet det igennem gentagne gange uden.

Ved testningen har jeg opdaget diverse fejl, som jeg har fået rettet. Eksempelvis kunne bolden sidde uhjælpeligt fast i væggen, hvis pladen maser bolden ind i væggen. Mange power-ups harmonerede heller ikke med hinanden til at starte med, hvor jeg fik rettet det meste. Power-up nr. 2, og nr. 4 og 5, som henholdsvis limer og giver flere bolde i spil, kunne jeg ikke få til at harmonere. Jeg har derfor gjort, at nr. 2 bliver slået fra, hvis der er flere bolde i spil.

Den eneste iøjefaldende fejl, som jeg ikke kan rette eller lappe over, er boldens uregelmæssige bane, når bolden nogle gange rammer brikken på bestemte punkter. Jeg har forsøgt med flere forskellige metoder at

Side 11

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 10 af 22 gøre boldens bane mere regelmæssig uden held. Derfor har jeg beholdt den nuværende bolds kollisionskode med afgørelsen af den nye vinkel på trods af, at den nogle gange er uregelmæssig.

Jeg har også testet for underholdningen og sværhedsgraden, hvor jeg vurderer, at begge de begge er i orden. Jeg synes, at spillet er sjovt, selvom det også kan være svært nogle steder.

Konklusion

Jeg kan konkludere, at det er lykkes for mig at lave et velfungerende spil, hvor der ikke er væsentlige fejl.

Jeg synes selv, at spillet er godt.

En af tingene, der kunne være markant bedre, er boldens kollision med brikkerne. Ellers er jeg tilfreds med spillet.

I forløbet med at lave spillet, har jeg fået lært meget om, hvordan man programmerer.

Bilag

Nedenfor er noten, som også er i afleveringsmappen:

Nedenfor har jeg vedlagt hele mit spil som kode: class something { float x; float y; float z;

float standartSpeed = 7;
float speed = 0;
float angle = TAU*0.75;

float radius; float width; float height;

PImage image; boolean right; boolean left; boolean start;

boolean alive = true;

boolean movement; int counter;

int level = 1;

Side 12

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 11 af 22

int colour = 1;
int lives = 3;

}

PImage ballImage;

PImage restartButton;

PImage question;

PImage kaboom;

PImage how;

PImage brickImage;

PImage brickImage1;

PImage brickImage2;

PImage brickImage3;

PImage powerUpImage;

PImage powerUpImage1;

PImage powerUpImage2;

PImage powerUpImage3;

PImage powerUpImage4;

PImage powerUpImage5;

PImage powerUpImage6;

PImage powerUpImage7;

PImage powerUpImage8;

PImage powerUpImage9;

PImage powerUpImage10;

PImage powerUpImage11;

PImage powerUpImage12;

PImage powerUpImage13; float i; float j; int e; int random;

int powerUpP = 1;
int ballType = 1;

int superCounter; int stickyCounter; float menuGap; boolean mouseOver; boolean restart; boolean glue; boolean sticky; boolean box;

//something ball = new something();
ArrayList<something> balls = new ArrayList();
ArrayList<something> bricks = new ArrayList();
something game = new something();
something plate = new something();
something extra = new something();
something laser = new something();
something bomb = new something();
ArrayList<something> toRemove = new ArrayList();
ArrayList<something> powerUps = new ArrayList();

void setup() { size(800, 600); textAlign(CENTER, CENTER); imageMode(CENTER); rectMode(CENTER);

ballImage = loadImage("1ball.png");
question = loadImage("Question.png");
restartButton = loadImage("Restart.png");
kaboom = loadImage("Kaboom.png");
how = loadImage("how.jpg");
brickImage = loadImage("1colour.png");
brickImage1 = loadImage("2colour.png");
brickImage2 = loadImage("3colour.png");
brickImage3 = loadImage("4colour.png");
powerUpImage = loadImage("skabelon.png");

Side 13

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 12 af 22

powerUpImage1 = loadImage("1.png");
powerUpImage2 = loadImage("2.png");
powerUpImage3 = loadImage("3.png");
powerUpImage4 = loadImage("4.png");
powerUpImage5 = loadImage("5.png");
powerUpImage6 = loadImage("6.png");
powerUpImage7 = loadImage("7.png");
powerUpImage8 = loadImage("8.png");
powerUpImage9 = loadImage("9.png");
powerUpImage10 = loadImage("10.png");
powerUpImage11 = loadImage("11.png");
powerUpImage12 = loadImage("12.png");
powerUpImage13 = loadImage("13.png");
laser.alive = false;
bomb.x = width/2;
bomb.y = 1000;
//Menulinje
menuGap = 40;
//Bolden
something ball = new something();
ball.image = ballImage;

balls.add(ball);

ball.radius = 10;
ball.x = 200;
ball.y = 200;
//Brikker
i = brickImage.width;
j = brickImage.height + menuGap;
//pladen
plate.x = width/2;
plate.y = height - 40;
plate.width = 100;
plate.height = 15;
plate.speed = 10;

} void draw() { background(128);

//boldtype
ballImage = loadImage(str(ballType)+"ball.png");
//Banebyggeren
if (game.level == 1) {
if (i <= width - brickImage.width) {
something brick = new something();

bricks.add(brick);

brick.colour = 3;
brick.image = brickImage;
brick.x = i;
brick.y = j;
i += brickImage.width + brickImage.height;

}

if (i > width - brickImage.width && j < height*0.30) {
i = brickImage.width;
j += brickImage.height * 2;

}

}

if (game.level == 2) {
if (i <= width - brickImage.width) {
something brick = new something();
brick.colour = 2;
brick.image = brickImage;

bricks.add(brick);

brick.x = i;
brick.y = j;
i += brickImage.width * 1.8;

}

Side 14

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 13 af 22

if (i > width - brickImage.width && j < height*0.5) {
i = brickImage.width*1.5;
j += brickImage.height;

}

}

if (game.level == 3) {

if (e < 70) {

something brick = new something();
brick.colour = (int) random(4) + 1;
if (brick.colour == 1) {
brick.image = brickImage;
} else if (brick.colour == 2) {
brick.image = brickImage1;
} else if (brick.colour == 3) {
brick.image = brickImage2;
} else if (brick.colour == 4) {
brick.image = brickImage3;

}

brick.image = brickImage;

bricks.add(brick);

brick.x = random(width - brick.image.width) + brick.image.width/2;
brick.y = random(height/2) + brick.image.height/2 + menuGap;
e += 1;

} for (something brick : bricks) {

brick.x -= 1;
if (brick.x + brick.image.width/2 < 0) {
brick.x = width + brick.image.width/2;

}

}

}

if (game.level == 4) {

if (e < 70) {

something brick = new something();
brick.image = brickImage;

bricks.add(brick);

brick.x = random(width - brick.image.width) + brick.image.width/2;
brick.y = random(height) + brick.image.height/2;
e += 1;

} for (something brick : bricks) {

brick.y -= 1;
if (brick.y + brick.image.height/2 - menuGap < 0) {
brick.y = height + brick.image.height/2;

}

}

}

if (game.level == 5) {
if (i <= width) {
something brick = new something();
brick.colour = 4;
brick.image = brickImage;

bricks.add(brick);

brick.x = i;
brick.y = j;
i += brickImage.width * 2;

}

if (i >= width && j <= height/2)

{

i = brickImage.width;
j += brickImage.height * 1.2;

}

if (bricks.size() == 96) {
game.movement = true;

} if (game.movement) { for (something brick : bricks) {

Side 15

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 14 af 22

brick.z += 0.10;
brick.x += 4 * cos(brick.z);
brick.y += 4 * sin(brick.z);

}

}

}

if (game.level == 6) {

if (e < 100) {

something brick = new something();
brick.colour = 2;
brick.image = brickImage;

bricks.add(brick);

brick.x = random(width - brick.image.width) + brick.image.width/2;
brick.y = random(height) + brick.image.height/2;
e += 1;

} for (something brick : bricks) {

brick.y += 1;
if (brick.y > height + brick.image.height/2) {
brick.y = menuGap - brick.image.height/2;

}

}

if (bricks.size() == 0) {

textSize(60);

text("You have won the game!!!", width/2, height*(2/4.0));

}

}

//Næste level
if (bricks.size() == 0 && game.level < 6) {
game.level += 1;
if (game.level == 2) {
i = brickImage.width*1.5;
j = brickImage.width;

} else {

i = brickImage.width;
j = brickImage.height + menuGap;

}

game.start = false;
game.movement = false;
laser.alive = false;

for (something ball : balls) { toRemove.add(ball);

}

ballType = 1;
glue = false;
e = 0;
plate.width = 100;
plate.height = 15;

for (something powerUp : powerUps) { toRemove.add(powerUp);

}

}

//Restart

if (restart) { for (something brick : bricks) { toRemove.add(brick);

} for (something ball : balls) {

i = brickImage.width;
j = brickImage.height + menuGap;
game.level = 0;
game.counter = 0;
game.start = false;
game.lives = 3;
game.movement = false;
laser.alive = false;
ball.speed = ball.standartSpeed;

Side 16

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 15 af 22

ballType = 1;
glue = false;
e = 0;
plate.width = 100;
plate.height = 15;

toRemove.add(ball);

} for (something powerUp : powerUps) { toRemove.add(powerUp);

}

restart = false;

}

//Skabelse af ny bold

if (balls.size() < 1) {

something ball = new something();
ball.image = ballImage;

balls.add(ball);

ball.radius = 10;
ball.x = 200;
ball.y = 200;
ball.speed = ball.standartSpeed;
ball.angle = TAU/8.0;

}

//Pladen

if (glue) { fill(0, 255, 0);

} else { fill(255);

} rect(plate.x, plate.y, plate.width, plate.height);

//Bevægelse af pladen

if (plate.left) {

plate.x -= plate.speed;

} if (plate.right) {

plate.x += plate.speed;

}

//Grænsen af plade
if (plate.x - plate.width/2 < 0) {
plate.x = plate.width/2;

}

if (plate.x + plate.width/2 > width) {
plate.x = width - plate.width/2;

} for (something ball : balls) {

//Brikken

for (something brick : bricks) {

if (brick.colour == 1) {

image(brickImage, brick.x, brick.y);

} else if (brick.colour == 2) {

image(brickImage1, brick.x, brick.y);

} else if (brick.colour == 3) {

image(brickImage2, brick.x, brick.y);

} else if (brick.colour == 4) {

image(brickImage3, brick.x, brick.y);

}

}

//bolden

image(ballImage, ball.x, ball.y);

//Bevægelse af bolden
if (sticky == false) {
ball.x += ball.speed * cos(ball.angle);
ball.y += ball.speed * -sin(ball.angle);

println(ball.angle);

}

if (game.start == false && game.lives > 0) {

textSize(50);

text("Press SPACE for start", width/2, height*(3/4.0));

Side 17

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 16 af 22

ball.speed = 0;
ball.x = plate.x;
ball.y = plate.y - ball.image.height;

}

if (game.alive == false) {

textSize(25);

text("Lost life!", width/2, height*(1/2.0));

}

if (game.lives == 0) {

textSize(25);

text("You have lost your balls!", width/2, height*(1.1/2.0));
text("Game over!", width/2, height*(1.1/2.0) + 50);

}

//boldens grænser
if (ball.x + ball.radius > width || ball.x - ball.radius < 0) {
ball.angle = TAU/2 - ball.angle;
//Rettelse af fejl
if (ball.x > width/2 && ball.y > plate.y - 30) {
ball.x -= ball.image.width;

}

if (ball.x < width/2 && ball.y > plate.y - 30) {
ball.x += ball.image.width;

}

} if (ball.y - ball.radius - menuGap < 0) {

ball.angle = -ball.angle;

}

//Død
if (ball.y + ball.radius > height && game.lives > 0) {

if (balls.size() > 1)

{ toRemove.add(ball);

} else {

game.alive = false;
game.lives -=1;
game.start = false;
laser.alive = false;
ball.speed = ball.standartSpeed;
ballType = 1;
glue = false;

if (plate.width < 100) {

plate.width = 100;

}

}

}

//Kollision mellem bold og plade
if ( dist(ball.x, 0, plate.x, 0) < ball.radius + plate.width/2
&& dist(ball.y, 0, plate.y, 0) < ball.radius + plate.height/2) {
float d = dist(ball.x, 0, plate.x, 0);
float angle = map(d, 0, plate.width/2, 0, TAU/6);

if (ball.x < plate.x) {

ball.angle = TAU/4 + angle;

} else {

ball.angle = TAU/4 - angle;

} if (ball.speed < ball.standartSpeed) {

ball.speed +=1;

} if (glue) {

sticky = true;
stickyCounter += 1;

}

if (stickyCounter >= 10) {
glue = false;

}

} if (sticky) {

Side 18

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 17 af 22 if (plate.right) {

ball.x += plate.speed;

} if (plate.left) {

ball.x -= plate.speed;

}

ball.y = plate.y - ball.image.height;

} if (balls.size() > 1) {

glue = false;

}

laser.y -= laser.speed;

for (something brick : bricks) {

//laser

if (laser.alive) {

laser.speed = 20;

fill(0, 0, 255); rect(laser.x, laser.y - 40, 10, 80); fill(255);

rect(plate.x, plate.y - plate.height/2, 15, plate.height*2);
if (dist(laser.x, 0, brick.x, 0) < brickImage.width/2 + 10/2
&& dist(laser.y, 0, brick.y, 0) < brickImage.height/2 + 80/2) {

toRemove.add(brick);

laser.y = - 100;

} if (laser.counter > 15) {

laser.alive = false;

}

}

//Brikker
//Boldens kollision med brikken
if ( dist(ball.x, 0, brick.x, 0) < ball.radius + brick.image.width/2 &&
dist(ball.y, 0, brick.y, 0) < ball.radius + brick.image.height/2 && ball.speed > 0) {
if (ballType == 2) {
superCounter += 1;

}

if (superCounter >= 30) {
ballType = 1;
superCounter = 0;

}

if (ballType == 1) {
//Over eller under
if (ball.x > brick.x - brick.image.width/2 && ball.x < brick.x + brick.image.width/2 && extra.height > 3) {
ball.angle = -ball.angle;
extra.height = 1;

println(1);

//siderne
} else if (ball.y > brick.y - brick.image.height/2 && ball.y < brick.y + brick.image.height/2 && extra.width > 3) {
ball.angle = TAU/2 - ball.angle;
extra.width = 1;

println(2);

//Kanterne
} else if ( dist(ball.x, 0, brick.x, 0) - ball.radius - brick.image.width/2 < dist(ball.y, 0, brick.y, 0) - ball.radius - brick.image.height/2 &&

extra.height > 3) {

ball.angle = -ball.angle;
extra.height = 1;

println(3);

} else if (dist(ball.x, 0, brick.x, 0) - ball.radius - brick.image.width/2 > dist(ball.y, 0, brick.y, 0) - ball.radius - brick.image.height/2 && extra.width

> 3) {

ball.angle = TAU/2 - ball.angle;
extra.width = 1;

println(4);

}

} toRemove.add(brick);

game.counter += 1;
//POWERUPS

Side 19

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 18 af 22

something powerUp = new something();
random = (int) random(1000);
if (random >= 1 && random <= 5) {
powerUp.colour = 1; //Superball
} else if (random >= 6 && random <= 20) {
powerUp.colour = 2; //Glue
} else if (random >= 21 && random <= 30) {
powerUp.colour = 3; //Laser
} else if (random >= 31 && random <= 43) {
powerUp.colour = 4; //Double
} else if (random >= 44 && random <= 53) {
powerUp.colour = 5; //Multiball
} else if (random >= 54 && random <= 63) {
powerUp.colour = 6; //XL
} else if (random >= 64 && random <= 73) {
powerUp.colour = 7; //XS
} else if (random >= 74 && random <= 78) {
powerUp.colour = 8; //1+
} else if (random >= 79 && random <= 90) {
powerUp.colour = 9; //Normalisering
} else if (random >= 91 && random <= 95) {
powerUp.colour = 10; //Plus fart
} else if (random >= 96 && random <= 100) {
powerUp.colour = 11; //minus fart
} else if (random >= 101 && random <= 200) {
powerUp.colour = 12; //10 point
} else if (random >= 201 && random <= 220) {
powerUp.colour = 13; //BOMBE!

}

if (random >= 1 && random <= 220) {

powerUps.add(powerUp);

if (powerUp.colour == 1) {
powerUp.image = powerUpImage1;
} else if (powerUp.colour == 2) {
powerUp.image = powerUpImage2;
} else if (powerUp.colour == 3) {
powerUp.image = powerUpImage3;
} else if (powerUp.colour == 4) {
powerUp.image = powerUpImage4;
} else if (powerUp.colour == 5) {
powerUp.image = powerUpImage5;
} else if (powerUp.colour == 6) {
powerUp.image = powerUpImage6;
} else if (powerUp.colour == 7) {
powerUp.image = powerUpImage7;
} else if (powerUp.colour == 8) {
powerUp.image = powerUpImage8;
} else if (powerUp.colour == 9) {
powerUp.image = powerUpImage9;
} else if (powerUp.colour == 10) {
powerUp.image = powerUpImage10;
} else if (powerUp.colour == 11) {
powerUp.image = powerUpImage11;
} else if (powerUp.colour == 12) {
powerUp.image = powerUpImage12;
} else if (powerUp.colour == 13) {
powerUp.image = powerUpImage13;

}

powerUp.x = brick.x;
powerUp.y = brick.y;

}

}

}

//Justering af vinkel

if (ball.angle > TAU) {

ball.angle -= TAU;

} else if (ball.angle < 0) {

Side 20

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 19 af 22

ball.angle += TAU;

}

}

extra.height +=1;
extra.width +=1;
//Kollision med powerUp

for (something powerUp : powerUps) {

if ( dist(powerUp.x, 0, plate.x, 0) < powerUpImage.width/2 + plate.width/2
&& dist(powerUp.y, 0, plate.y, 0) < powerUpImage.height/2 + plate.height/2) {
if (powerUp.colour == 1) {
ballType = 2;
superCounter = 0;

}

if (powerUp.colour == 2 && balls.size() == 1) {
glue = true;
stickyCounter = 0;

}

if (powerUp.colour == 3) {
laser.alive = true;
laser.counter = 0;

}

if (powerUp.colour == 4)

{

something ball = new something();
ball.image = ballImage;

balls.add(ball);

ball.radius = 10;
ball.x = plate.x;
ball.y = plate.y;
ball.speed = ball.standartSpeed;

}

if (powerUp.colour == 5)

{

for (int i = 0; i < 6; i += 1)

{

something ball = new something();
ball.image = ballImage;

balls.add(ball);

ball.radius = 10;
ball.x = width/2;
ball.y = height/2;
ball.angle = TAU * (i/6.0) + TAU/12;
ball.speed = ball.standartSpeed;

}

}

if (powerUp.colour == 6) {
plate.width *= 1.5;

}

if (powerUp.colour == 7) {
plate.width /= 1.5;

}

if (powerUp.colour == 8) {
game.lives += 1;

}

if (powerUp.colour == 9) {
ballType = 1;
glue = false;
laser.alive = false;
plate.width = 100;

for (something ball : balls) {

ball.speed = ball.standartSpeed;

}

}

if (powerUp.colour == 10) {

for (something ball : balls) {

ball.speed += 3;

Side 21

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 20 af 22

}

}

if (powerUp.colour == 11) {

for (something ball : balls) {

ball.speed -= 5;

if (ball.speed < 1) {

ball.speed = 1;

}

}

}

if (powerUp.colour == 12) {
game.counter += 10;

}

if (powerUp.colour == 13) {
bomb.y = height/2;

} toRemove.add(powerUp);

}

}

//menuboks

fill(255);

rect(width/2, menuGap/2, width, menuGap);
image(question, 775, menuGap/2);
image(restartButton, 645, menuGap/2);
//tekst

fill(0); textSize(25);

text("Point: " + game.counter, 255, 17);
text("Level: " + game.level, 55, 17);
text("Lives: " + game.lives, 455, 17);

fill(255);

//om powerUps

for (something powerUp : powerUps) {

if (powerUp.colour == 1) {

image(powerUpImage1, powerUp.x, powerUp.y);

} else if (powerUp.colour == 2) {

image(powerUpImage2, powerUp.x, powerUp.y);

} else if (powerUp.colour == 3) {

image(powerUpImage3, powerUp.x, powerUp.y);

} else if (powerUp.colour == 4) {

image(powerUpImage4, powerUp.x, powerUp.y);

} else if (powerUp.colour == 5) {

image(powerUpImage5, powerUp.x, powerUp.y);

} else if (powerUp.colour == 6) {

image(powerUpImage6, powerUp.x, powerUp.y);

} else if (powerUp.colour == 7) {

image(powerUpImage7, powerUp.x, powerUp.y);

} else if (powerUp.colour == 8) {

image(powerUpImage8, powerUp.x, powerUp.y);

} else if (powerUp.colour == 9) {

image(powerUpImage9, powerUp.x, powerUp.y);

} else if (powerUp.colour == 10) {

image(powerUpImage10, powerUp.x, powerUp.y);

} else if (powerUp.colour == 11) {

image(powerUpImage11, powerUp.x, powerUp.y);

} else if (powerUp.colour == 12) {

image(powerUpImage12, powerUp.x, powerUp.y);

} else if (powerUp.colour == 13) {

image(powerUpImage13, powerUp.x, powerUp.y);

}

powerUp.y += 3;
if (powerUp.y > height + powerUpImage.height/2) {

toRemove.add(powerUp);

}

} println(powerUps.size());

//musemarkør

Side 22

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 21 af 22

if (dist(mouseX, mouseY, 775, menuGap/2) < question.width/2 ||
(dist(mouseX, 0, 645, 0) < restartButton.width/2 && dist(mouseY, 0, menuGap/2, 0) < restartButton.height/2)) {

cursor(HAND);

mouseOver = true;

} else { cursor(ARROW);

mouseOver = false;

}

//Bombe

image(kaboom, bomb.x, bomb.y); if (bomb.y < 1000) {

bomb.y += 5;

} if (box) {

image(how, width/2, height/2);

}

if (mousePressed && dist(mouseX, mouseY, 775, menuGap/2) > question.width/2) {
box = false;

}

//Fjernelse af ting

powerUps.removeAll(toRemove); bricks.removeAll(toRemove); balls.removeAll(toRemove); toRemove.clear();

} void keyPressed() {

if (key == 'a') {
plate.left = true;

}

if (key == 'd') {
plate.right = true;

} for (something ball : balls) {

if (key == ' ' && game.lives > 0 && ball.speed == 0) {
game.start = true;
game.alive = true;
ball.speed = ball.standartSpeed;

}

//GAMETESTER
if (key == ' ' && mousePressed)

{ if (mouseY < ball.y & mouseX > ball.x) {

ball.angle = asin(dist(mouseY, 0, ball.y, 0)/dist(mouseX, mouseY, ball.x, ball.y));

} else if (mouseY > ball.y & mouseX > ball.x) {

ball.angle = - asin(dist(mouseY, 0, ball.y, 0)/dist(mouseX, mouseY, ball.x, ball.y));

} else if (mouseY < ball.y & mouseX < ball.x) {

ball.angle = TAU/2 - asin(dist(mouseY, 0, ball.y, 0)/dist(mouseX, mouseY, ball.x, ball.y));

} else {

ball.angle = TAU/2 + asin(dist(mouseY, 0, ball.y, 0)/dist(mouseX, mouseY, ball.x, ball.y));

}

}

}

} void keyReleased() {

if (key == 'a') {
plate.left = false;

}

if (key == 'd') {
plate.right = false;

}

if (key == ' ') {
sticky = false;

if (laser.y < 0) {

laser.x = plate.x;

Side 23

Hold: 14xad Programmering C

HTX – Aarhus Gymnasium

Side 22 af 22

laser.y = plate.y;
laser.counter += 1;

}

}

//Tester

for (something brick : bricks) {

if (key == 'p' && mousePressed) {

toRemove.add(brick);

}

} for (something ball : balls) {

if (key == '1') {
something powerUp = new something();

powerUps.add(powerUp);

powerUp.image = powerUpImage1;
powerUp.colour = 1;
powerUp.x = ball.x;
powerUp.y = ball.y;

}

if (key == '2') {
something powerUp = new something();

powerUps.add(powerUp);

powerUp.image = powerUpImage2;
powerUp.colour = 2;
powerUp.x = ball.x;
powerUp.y = ball.y;

}

if (key == '3') {
something powerUp = new something();

powerUps.add(powerUp);

powerUp.image = powerUpImage5;
powerUp.colour = 5;
powerUp.x = ball.x;
powerUp.y = ball.y;

}

if (key == '4') {
something powerUp = new something();

powerUps.add(powerUp);

powerUp.image = powerUpImage13;
powerUp.colour = 13;
powerUp.x = ball.x;
powerUp.y = ball.y;

}

}

} void mousePressed() {

if (dist(mouseX, 0, 645, 0) < restartButton.width/2 && dist(mouseY, 0, menuGap/2, 0) < restartButton.height/2) {
restart = true;
game.alive = true;

}

if (dist(mouseX, mouseY, 775, menuGap/2) < question.width/2) {
box = true;

}

}

Se opgaven i originaldokumentet eller gå til tekstens begyndelse.

Materialet

Fuld skærm

Opgaven åbner, når du ruller ned til den.