Guide: Hur du gör ett mobilspel för Android, iOS

Diskussion i 'Frågor, support och diskussion' startad av maosk21, 16 dec 2015.

  1. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Hej!

    Jag tänkte skapa en tråd där jag går igenom grunderna om hur man skapar ett mobilspel.

    Här kan ni se några av mina tidigare spel: https://play.google.com/store/search?q=gosetech&c=apps

    Samt: https://play.google.com/store/apps/developer?id=Maseapps+Ltd

    Exempel på spel utvecklat av mig & kollega - med LibGDX:





    Tillvägagång kommer att presenteras med bilder & Youtubesnuttar.

    Spelet kommer använda sig av biblioteket LibGDX: https://libgdx.badlogicgames.com/
    Och utvecklas i Android Studio: http://developer.android.com/tools/studio/index.html
    Spelet kommer att simuleras i: Bluestacks: http://www.bluestacks.com/
    Vi kommer visa annonser i vårat program med Google Admob https://www.google.com/admob/

    Spelet kommer att fungera i IOS, ANDROID, HTML5

    Spelet kommer att utvecklas i Java.

    Guiden kommer att ha följande innehåll:
    1. Installation, öppna ett projekt
    2. Visa en textur på skärmen
    3. Flytta Texturen med fingret
    4. Skala spelet på alla enheter
    5. Collision Detection
    6. Musik & Ljudeffekter
    7. All kod & nedladdningslänk till projektet
    8. Visa annonser i ditt spel(tjäna pengar! Wohoo!)
    Senare i utvecklingen
    • Visa annonser i ditt spel
    • Integrera med Google Play Game services(Leaderboards, achievements)
    Spelet kommer att vara väldigt simpelt & tanken är att lära ut endast grunderna.

    Det finns mängder av spelbibiliotek att välja bland. Bland annat LibGDX som jag har valt för denna guide.

    Varför LibGDX?
    • Enkelt uppbyggt, tar hand om jobbiga procedurer som vi slipper skriva själva
    • Kompilerar din Java kod åt alla plattformar
    • Stöd för flera tillägg, t.e.x SPINE(i spine gör man animationer).

    Nog om det! Nu kör vi!

    ----------------------------------------------------------------------------------

    1.0 Installation, öppna ett projekt

    Innan vi börjar med att göra vårt spel, så måste vi bestämma oss vad vi ska utveckla spelet i.

    Som nämnt innan använder jag spelbiblioteket LibGDX, samt kompilatorn Android studio.
    När nedladdningarna är klara är det dags att installera vår utvecklingsmiljö.
    • Börja med att installera JDK, Detta borde bara vara att installera.
      Här finns en installationsvide:o
      (inte min video)

    • Därefter installerar vi Android Studio, Borde bara vara att installera(Det kan ta ett tag för Android studio att starta för första gången).

    • Till sist "installerar" vi LibGDX. Öppna Libgdx filen du laddat ner.
      Så här ser det ut när du öppnar installationsfilen för Libgdx:[​IMG]
      (Jag väljer endast Android i denna Turtorial. Detta för att jag bara har Android telefoner hemma, DOCK kommer samma kod att fungera till alla plattformar)
    • Ange valfritt namn(det är enklast om du bara kopierar allt jag gör)
    • Välj ett namn för Package(spelar ingen roll vad du anger här)
    • Välj ett namn för din main class(spelar ingen roll vad du anger här)
    • Skapa en ny mapp(som jag gjort ovan, se bild). Här kommer vi att extrahera projektet som libgdx skapar åt oss
    • Ange sökväg för din SDK. Enklaste sättet att hitta din sökväg är att öppna Android Studio -> Tools -> Android -> SDK Manager - > Här borde du se din SDK Path
    Nu är allt klart & projektet är redo att skapas! Tryck på Generate & ditt LibGDX projekt kommer att extraheras. (OBS! När du genererar ett projekt för första gången kan det ta lång tid att skapa projektet. Detta för att LibGDX uppdaterar & laddar ner filer).

    Nu är det dags att öppna vårt projekt i Android Studio!

    Öppna Android Studio och öppna projektet du precis skapat:

    [​IMG]

    • Välj den mapp dit du extraherade LibGdx projektet
    • Dubbelklicka på Build.Gradle


    ----------------------------------------------------------------------------------

    2.0 - Visa en Textur på skärmen

    Om allt gick bra i steg 1.0 så borde du nu ha projektet öppnat & det borde se ut så här:

    (Denna kod som LibGdx har skrivit fungerar att köra, prova att köra koden. En bild & en röd bakgrund kommer att synas, för att testköra: Android -> run).

    [​IMG]

    OBS! Du måste ha en virtuell enhet installerad för att testköra. Öpnna BlueStacks & Android Studio kommer att hitta den automatiskt när du testkör ditt program:(

    OBS!
    All kod skrivs i core/ditt package / din main class. Se bild:
    [​IMG]

    Kod:
    package com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    
    public class turtorial_class extends ApplicationAdapter {
    SpriteBatch batch;
    Texture img;
    
    @Override
    public void create () {
    batch = new SpriteBatch();
    img = new Texture("badlogic.jpg");
    }
    
    @Override
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    batch.draw(img, 0, 0);
    batch.end();
    }
    }
    
    Kod som LibGDX automatiskt skapat åt oss
    (som jag nämnt ovan går det redan nu att testköra detta program. Det kan vara bra att göra så du vet att allt fungerar som det ska)

    Kod:
    package com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    public class turtorial_class extends ApplicationAdapter {
    
    @Override
    public void create () {
    
    }
    
    @Override
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    }
    }
    
    Vi börjar med att rensa all Kod som LibGDX redan har skrivit åt oss! Så det ser ut som ovan

    Kod:
    package com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    public class turtorial_class extends ApplicationAdapter {
    
    // olika bibliotek som tillhandahålls av LibGDX, t.ex. för att visa bilder, texturer på skärmen, input o.s.v.
    
    ------------------------------------------------------
    
    // här kommer vi att deklarera olika fältobjekt & variabler
    ------------------------------------------------------
    
    //inuti metoden create laddar vi in all vår data vi kommer att använda i spelet. T.ex. Ljud, bilder, fonts, effekter, objekt, animationer. Denna metod exekveras direkt när programmet startar. Så att all data, media finns tillgänglig direkt.
    @Override
    public void create () {
    
    }
    
    
    // inuti render kommer all rendering & uträkning att ske. Här ger vi bakgrunden en röd färg.
    @Override
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    }
    
    }
    
    
    Vad betyder nu all denna kod?(se kommentarer i koden ovan)

    ----------------------------------------------------------------------------------------------------------

    Nu är det dags att börja koda!
    Jag kommer att skriva koden som ovan inom "code" taggar, samt kommentera det jag gör. Därefter kommer jag att lägga ut en bild på hur allt ska se ut inan vi går till nästa kapitel!

    Vi börjar med att definiera samt skapa en batch och en textur(en batch används för att rendera texturer och ansvarar för att rita ut vår bild/textur på skärmen:(

    Steg 1 - Metoden create & fält
    Vi skapar en textur & en batch.

    Kod:
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera de objekt vi kommer att använda
    SpriteBatch vår_batch; // all rendering & ritning på skärmen sker genom vår batch
    Texture vår_bild; // här kommer vi senare att ladda in vår textur, bild
    
    @Override
    public void create () {
    vår_batch = new SpriteBatch(); // vi skapar vårt batchobjekt
    vår_bild = new Texture("objekt1.png"); // vi skapar vårt texturobjekt. Notera att vi skickar med sökvägen till den bild vi vill använda.
    }
    
    
    Steg 2 - Metoden render
    Vi ritar ut vår textur på skärmen.

    Kod:
    
    @Override
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1); // Ange en röd bakgrunds färg
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // LibGDX stuff
    
    vår_batch.begin();   // starta rendering
    vår_batch.draw(vår_bild, 0, 0);
    vår_batch.end(); // avsluta rendering
    }
    
    
    Vi måste alltid innan vi ritar ut en bild, Textur tala om det för datorn.

    Detta genom din_batch.begin(); & avsluta när du är klar med din_batch.end();

    Koden ovan ritar ut texturen vår_bild på kordinaterna X=0, Y=0. Vilket är nedre vänstra hörnet av vårt fönster

    Steg 3 - Koden är klar & vi testkör den
    Vår kod för att visa en textur på skärmen är nu klar & borde nu se ut såhär:

    Kod:
    importcom.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild;
    
    @Override
    public void create () {
    vår_batch = new SpriteBatch(); // skapa vår batch
    vår_bild = new Texture("objekt1.png"); // skapa vår textur
    }
    
    @Override
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    vår_batch.begin();
    vår_batch.draw(vår_bild, 0, 0); // visa vår bild på skärmen
    vår_batch.end();
    }
    }
    
    

    Innan vi går till nästa kapitel så Testkör vi programmet:

    [​IMG]

    Koden borde nu se ut som ovan


    [​IMG]


    Vårt objekt består av den blå kuben som placerats på kordinaterna X=0, Y=0

    Vikitgt att ta med sig från kapitel 2:
    • Alla texturer, ljudfiler, fonts osv placeras i mappen Assets inuti din projektmapp
    • Alla objekt skapar vi inuti metoden create
    • Metoden Render står för uträkningar & att visa texturer på skärmen
    Detta avslutar kapitel 2


    ----------------------------------------------------------------------------------

    3.0 - Flytta Texturen med fingret, Touch input

    I detta avsnitt visar jag hur du kan flytta kuben / objektet med fingret & hur man hanterar input. Vi kommer att fortsätta i samma kod som vi arbetade med i avsnitt 1.

    Steg 1 - Lägg till X & Y variabler som fält.

    Kod:
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild;
    
    // Vi börjar med att lägga till två variabler som fält. Dessa variabler blir globala & kan nås av alla metoder i programmet.
    Variablerna kommer hålla X & Y kordinaterna
    
    int X, Y;
    
    @Override
    public void create () {
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    }
    
    Vi har lagt till 2 variabler X & Y som ska hålla kordinaterna för input

    Steg 2 - Lägg till en metod för hantering av input

    Nedan lägger vi till en ny metod för att hantera input

    Kod:
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    X = Gdx.input.getX();
    Y = Gdx.input.getY();
    }
    
    
    X & Y kordinaterna från användarens "touch" hämtas & lagras i variablerna X respektive Y.

    Metodenför input har jag skrivit under metoden render();

    Steg 3 - Anropa vår nya metod för input samt koppla vårt objekt till X & Y variablerna

    Kod:
    
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    input(); // anropa vår metod för input
    
    vår_batch.begin();
    vår_batch.draw(vår_bild, X, Y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    
    I vår render metod anropar vi nu vår nya metod 'input()', som lagrar användarens X & Y kordinater. Vi har sedan kopplat vårat objekt till variablerna X & Y som vi skapade i steg 2.

    Objektet kopplas till användarens input genom att byta:
    vår_batch.draw(vår_bild, 0, 0);
    till:
    vår_batch.draw(vår_bild, X, Y);

    Steg 4 - Testkör programmet

    Vår hantering av input är klar för stunden & redo att testköras!

    Såhär bör all kod se ut nu:

    Kod:
    package com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild;
    
    int X, Y;
    
    @Override
    public void create () {
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    }
    
    @Override
    public void render () {
    
    Gdx.gl.glClearColor(1, 0, 0, 1); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    input(); // anropa vår metod för input
    
    vår_batch.begin();
    vår_batch.draw(vår_bild, X, Y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    X = Gdx.input.getX();
    Y = Gdx.input.getY();
    }
    }
    
    Koden fungerar MEN!

    Ett problem som du kanske märker är att input för Y är inverterad!

    D.v.s.
    Tvärt om!

    Varför då?

    Jo! Androids kordinatsystem matchar nämligen inte LibGDX:
    [​IMG]

    Oroa er inte vi löser detta i nästa kapitel. . . Som kommer NU!


    ----------------------------------------------------------------------------------

    4.0 - Skala Spelet på alla enheter

    I detta kapitel kommer vi skala spelet på alla enheter, så att det fungerar likadant både på stora & små skärmar. Samtidigt kommer problemet i förra kapitlet med inverterat kordinatsystem att lösas.

    Steg 1 - Lägg till nya fältvariabler & ortographic camera

    Kod:
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    
    Texture vår_bild;
    
    int X, Y; // våra variabler för user input
    
    float scrw = 1280, scrh = 720; // ange den upplösing vi vill jobba med
    
    OrthographicCamera camera; // vi kommer att använda en Ortographic Camera som vi döper till camera
    
    Vector3 cords; // vector att lagra våra nya korrigerade cordinater från touch input
    
    
    Ovan deklarerar vi en Ortographic Camera: https://github.com/libgdx/libgdx/wiki/Orthographic-camera, samt anger den bredd & höjd i antalet pixlar vårat spel ska köras i.

    Vi talar också om att vi vill använda en Vector. Denna ska senare användas för våra kordinater från user input

    Steg 2 - Skapa vår ortographic camera & vår vector för kordinater

    Kod:
    
    public void create () {
    
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    
    // skapa en ortographic camera & sätt dess width & height till den upplösning vi vill ha
    camera = new OrthographicCamera();
    camera.viewportHeight = scrh;
    camera.viewportWidth = scrw;
    
    cords = new Vector3(); // skapa vectorn för input
    
    }
    
    

    Kameran skapas i vår create metod & får en bredd & höjd. Vår nya vector som ska innehålla nya fungerande kordinater för user input skapas också här.

    Steg 3 - använd vår ortographic camera
    Nu när vi skapat vår Ortographic camera är det dags att använda den.

    Vår render metod måste uppdateras:

    Kod:
    
    public void render () {
    Gdx.gl.glClearColor(1, 0, 0, 1); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f); // skalas korrekt på alla enheter
    camera.update(); // updatera vår kamera för varje loop
    
    input(); // anropa vår metod för input
    
    vår_batch.begin();
    vår_batch.draw(vår_bild, X, Y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    

    Steg 4 - Koppla våra texturer & grafik till vår ortographic camera
    Viktigt steg! Gör vi inte detta kommer vår grafik att placeras enligt Anroids kordinatsystem

    Gör följande ändring i din Render metod:

    Kod:
    vår_batch.begin();
    vår_batch.draw(vår_bild, X, Y); // visa vår bild på skärmen
    vår_batch.end();
    
    Måste ändras till:

    Kod:
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined); // Lägg till detta
    vår_batch.draw(vår_bild, X, Y); // visa vår bild på skärmen
    vår_batch.end();
    

    Ovan berättar vi att vår textur ska använda vår Ortographic Camera och ritas efter denna.
    Detta måste göras för alla texturer vi ritar ut på skärmen. Annars kommer olika kordinatsystem att användas.

    Steg 5 - Rätt kordinater för user input
    Äntligen kan vi fixa till rätt kordinater för user input. D.v.s. Att exakt reigistrera var användaren rör på skärmen.

    Vi kommer att använda Vectorn cords vi skapade i steg 1 & 2.

    Vi behöver endast göra följande ändringar i metoden input för att få allt att fungera:

    Ändra nedanstående kodsnutt:
    Kod:
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    X = Gdx.input.getX();
    Y = Gdx.input.getY();
    }
    
    Till

    Kod:
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    cords = new Vector3(Gdx.input.getX() , Gdx.input.getY(), 0); // hämta våra nya kordinater
    camera.unproject(cords); // applicera på vår ortographic camera
    }
    
    Nu är allt fixat!

    Nu ska spelet skalas till alla enheter som existerar samt våra kordinater för input fungerar!

    Steg 6 - Ersätt våra gamla input kordinater med våra nya

    Ändra följande i metoden Render:

    Kod:
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined);
    vår_batch.draw(vår_bild, X, Y); // visa vår bild på skärmen
    vår_batch.end();
    
    Till

    Kod:
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined);
    vår_batch.draw(vår_bild, cords.x, cords.y); // visa vår bild på skärmen
    vår_batch.end();
    
    X & Y har ändrats till cords.x & cords.y
     
    Last edited: 10 sept 2017
    RuffyMan, bernard, Cubiz och 3 andra gillar detta.
  2. Spiderwolf

    Spiderwolf Teen Droid Medlem

    Blev medlem:
    11 okt 2011
    Inlägg:
    307
    Mottagna gillanden:
    7
    Operatör:
    TRE....
    Telefon:
    Iphone 8 + 64gb

    MINA ENHETER

    Operatör:
    TRE....
    Telefon:
    Iphone 8 + 64gb
    Platta:
    iPad 5th gen
    Jag skulle mycket gärna vilja följa detta!

    För att förstå hur ett mobilspel fungerar och även det som ligger bakom själva "skynket".
     
    Avarell_Dalton gillar detta.
  3. bvb

    bvb Solbränd Android Medlem

    Blev medlem:
    1 feb 2011
    Inlägg:
    3 416
    Mottagna gillanden:
    1 420
    Operatör:
    Tre Telia Hallon Halebop

    MINA ENHETER

    Operatör:
    Tre Telia Hallon Halebop
    Platta:
    Apple iPad Mini
    Övrigt:
    Chromecast x6
    Kul idé! :)

    Fler guider och tutorials på forumet är bara positivt.
     
  4. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Trevligt med intresse! Tänkte att det finns knappt några svenska bra guider, så jag tänkte dela med mig av det jag lärt mig!

    Jag har nu börjat att uppdatera guiden & den kommer att fyllas på med tiden!
     
    RuffyMan gillar detta.
  5. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Steg 7 - Så här ser hela koden ut nu:
    Vi är klara & all kod bör se ut så här nu:

    Kod:
    package com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    import com.badlogic.gdx.math.Vector3;
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild;
    
    int X, Y;
    float scrw = 1280, scrh = 720;
    
    OrthographicCamera camera;
    Vector3 cords; // vector att lagra våra nya korrigerade cordinater från touch imput
    
    @Override
    public void create () {
    
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    
    // skapa en ortographic camera & sätt dess width & height till den upplösning vi vill ha
    camera = new OrthographicCamera();
    camera.viewportHeight = scrh;
    camera.viewportWidth = scrw;
    
    cords = new Vector3(); // skapa vectorn för input
    }
    
    @Override
    public void render () {
    
    Gdx.gl.glClearColor(1, 0, 0, 1); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
    camera.update();
    
    input(); // anropa vår metod för input
    
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined);
    vår_batch.draw(vår_bild, cords.x, cords.y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    cords = new Vector3(Gdx.input.getX() , Gdx.input.getY(), 0);
    camera.unproject(cords);
    }
    }
    
    Youtubessnutt:


    Nu till nästa avsnitt!

    ----------------------------------------------------------------------------------

    5.0 - Collision Detection
    I detta avsnitt ska vi arbeta med Collision Detection! Som är ett av de viktigare momenten inom spelprogrammering!

    Det finns nästan inga grafiska spel som inte använder sig utav det(kanske något text baserat spel).

    Vad är Collision Detection?
    Enkelt förklarat är det att tala om för datorn när ett eller flera objekt kolliderar med varandra!

    Nu har LibGDX en inbyggd simpel class/metoder för att ta reda på när objekt kolliderar med varandra.

    Kod:
    if(rectangle1.overlaps(rectangle2)){
    //objekt har kolliderat
    };
    
    Ovanstående kod kollar om Rektangel 1 har kolliderat med Rektangel 2
    Givetvis gör denna kod ingenting i dagsläget.

    Vi kommer inte att använda LibGDX färdiga metoder för collision Detection utan vi kommer skapa en helt egen Class för detta ändamål!

    Steg 1 - Skapa en ny class för collision Detection!

    [​IMG]
    • I Android Studio högerklicka på din mainclass & skapa en ny klass
    • Döp klassen till collision_detection

    Steg 2 - konfigurera den nya klassen

    Nu måste vi tänka hur vår klass ska vara uppbyggd!

    Vår klass för collision detection kommer att bestå av en konstruktor, samt en metod för att uträkna om kollision har skett.

    Konstruktorn kommer inte att ta några argument, utan vår metod för kollidering kommer att göra det(den kommer att ta X & Y värde för objekt och spelare)

    Konstruktorn kommer endast att skapa våra Rektanglar för det objekt som ska kollidera. Samt ange dess bredd

    Tryck på vår nya class och skriv följande kod:
    Kod:
    
    public class collision_detection {
    
    // deklarering
    
    Rectangle Object_rectangle;
    Rectangle Player_rectangle;
    
    //skapa
    collision_detection(){
    
    // skapa våra rektanglar
    Object_rectangle = new Rectangle();
    Player_rectangle = new Rectangle();
    
    // Ange bredd & höjd på rektanglar
    Object_rectangle.width = 100;
    Object_rectangle.height = 100;
    Player_rectangle.width = 100;
    Player_rectangle.height = 100;
    }
    
    
    Har konfigurerar vi konstruktorn att skapa 2 Rektanglar & anger dess bredd & höjd i pixlar.

    Vad ska vi ha dessa Rektanglar till?

    Rektanglarna kommer att placeras med EXAKT position över våra objekt/texturer, så att vi sedan kan räkna ut om objekten har kolliderat.


    Steg 3 - Skapa vår Metod för uträkning om kollision har skett

    Nu måste vi skapa en ny metod för uträkning! Skapa en metod under konstruktorn döp den till "check_collision"()

    Vår metod kommer att ta X, & Y värde som argument från vår Main_class(vår turtorial_class). X & Y värdena kommer att representera Position för användarens touch samt possitionen för det objektet vi ska kollidera med.

    Vi kommer även att skapa lokala variabler inom klassen, som jag inte tror att jag behöver förklara.

    Vår metod:

    Kod:
    public boolean check_collision(Vector3 cords_player, float object_X, float object_Y){
    
    // Applicera våra uppdaterade kordinater på vårt objekt som vi ska kollidera med
    Player_rectangle.x = cords_player.x; Player_rectangle.y = cords_player.y;
    
    Object_rectangle.x = object_X; Object_rectangle.y = object_Y;
    
    //användare, objekt
    float leftA, leftB;
    float rightA, rightB;
    float topA, topB;
    float bottomA, bottomB;
    
    boolean check = false;
    
    // Beräkna sidor för Spelare
    leftA = Player_rectangle.x;
    rightA = Player_rectangle.x + Player_rectangle.width;
    topA = Player_rectangle.y + Player_rectangle.height;
    bottomA = Player_rectangle.y;
    
    //Beräkna sidor för objektet
    leftB = Object_rectangle.x;
    rightB = Object_rectangle.x + Object_rectangle.width;
    topB = Object_rectangle.y + Object_rectangle.height;
    bottomB = Object_rectangle.y;
    
    // kolla om en sida överskrider en sida av objekt. Om så är fallet har en kollision skett!
    if (topA >= bottomB && bottomA <= topB && rightA >= leftB && leftA <= rightB)
    {
    check = true;
    Gdx.app.exit();
    }
    
    return check;
    }
    
    Vad gör nu vår metod?

    Kolla kommentarer ovan!

    För att beskriva lite snabbt, så hämtar vi spelarens kordinater från vår main klass, samt objektets kordinater.

    Sedan kalkylerar vi bredd, sidor o.s.v.

    Dessa använder vi sedan för att kolla om spelaren har kolliderat med objektet!

    Nu är vår klass för en simpel collision detection klar!

    Kod för hela klassen:

    Kod:
    
    public class collision_detection {
    
    // deklarering
    Rectangle Object_rectangle;
    Rectangle Player_rectangle;
    //skapa
    collision_detection(){
    
    // skapa våra rektanglar
    Object_rectangle = new Rectangle();
    Player_rectangle = new Rectangle();
    
    // Ange bredd på rektanglar
    Object_rectangle.width = 100;
    Object_rectangle.height = 100;
    Player_rectangle.width = 100;
    Player_rectangle.height = 100;
    }
    
    public boolean check_collision(Vector3 cords_player, float object_X, float object_Y){
    
    // Applicera våra uppdaterade kordinater på vårt objekt som vi ska kollidera med
    
    Player_rectangle.x = cords_player.x; Player_rectangle.y = cords_player.y;
    Object_rectangle.x = object_X; Object_rectangle.y = object_Y;
    
    // Skapar lite onödiga vraibler för att det ska bli lättare att förstå
    //användare, objekt
    float leftA, leftB;
    float rightA, rightB;
    float topA, topB;
    float bottomA, bottomB;
    
    boolean check = false;
    
    // Beräkna sidor för Spelare
    leftA = Player_rectangle.x;
    rightA = Player_rectangle.x + Player_rectangle.width;
    topA = Player_rectangle.y + Player_rectangle.height;
    bottomA = Player_rectangle.y;
    
    //Beräkna sidor för objektet
    leftB = Object_rectangle.x;
    rightB = Object_rectangle.x + Object_rectangle.width;
    topB = Object_rectangle.y + Object_rectangle.height;
    bottomB = Object_rectangle.y;
    
    // kolla om en sida överskrider en sida av objekt. Om så är fallet har en kollision skett!
    if (topA >= bottomB && bottomA <= topB && rightA >= leftB && leftA <= rightB)
    {
    check = true;
    Gdx.app.exit();  // avsluta progarmmet om kollision sker
    }
    
    return check;
    }
    
    }
    
    
    Japp klassen är helt klar & fungerande!

    MEN!

    För att få allt att fungera måste vi koppla ihop den & anropa medtoden från vår main_class.

    Detta gör vi i steg 4!


    Steg 4 - Modifiera din main_class d.v.s. din turtorial_class. För att aktivera collision detection

    Innan vi kan använda vår collision_detection klass måste vi skapa ett objekt av denna. Detta gör vi genom att först deklarera vårat objekt, och sedan skapa det i metoden create.

    Kod:
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild;
    
    int X, Y;
    
    float scrw = 1280, scrh = 720;
    
    OrthographicCamera camera;
    
    // vector att lagra våra nya korrigerade cordinater från touch imput
    Vector3 cords;
    
    
    // deklarera ett objektet vi ska använda för collision detection
    collision_detection COLLISION;
    
    
    Ovan deklarerar vi ett objekt för collision detection(detta gör vi i vår turtorial_class)

    Kod:
    
    public void create () {
    
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    
    // skapa en ortographic camera & sätt dess width & height till den upplösning vi vill ha
    camera = new OrthographicCamera();
    camera.viewportHeight = scrh;
    camera.viewportWidth = scrw;
    cords = new Vector3(); // skapa vectorn för input
    
    COLLISION = new collision_detection(); // skapa objekt för collision detection
    
    }
    
    Ovan skapar vi vårat objekt för collision detection

    STEG 5 - Det är dags att anropa vår metod för Collision Detection!
    Nu ska vi anropa metoden check_collision från vår metod collision_detection & skapa ett objekt att kollidera med.

    Vi börjar med att skapa 2 variabler för det objekt vi ska kollidera med. Variablerna är X & Y kordinaterna för det objekt vi ska kollidera med

    Vi lägger till variablerna som fält:
    Kod:
    
    public class turtorial_class extends ApplicationAdapter {
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild;
    
    int X, Y;
    
    float OBJECT_X, OBJECT_Y; // kordinater för objektet vi ska kollidera med
    
    boolean COLLIDED = false;
    
    float scrw = 1280, scrh = 720;
    
    
    Vi har lagt till variablerna OBJECT_X & OBJECT_Y, samt COLLIDED

    Nu kan vi anropa vår metod från klassen collision_detection. I vår Render metod lägger vi till följande:
    Kod:
    public void render () {
    
    Gdx.gl.glClearColor(1, 0, 0, 1); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
    camera.update();
    
    input(); // anropa vår metod för input
    
    COLLIDED = COLLISION.check_collision(cords, OBJECT_X, OBJECT_Y); // kolla om kollision sker
    
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined);
    vår_batch.draw(vår_bild, cords.x, cords.y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    Vi kollar kollision genom att ha lagt till följande:
    Kod:
     COLLIDED = COLLISION.check_collision(cords, OBJECT_X,OBJECT_Y); 
    Nu är allt klart & vi har en fungerande collision detection!

    Steg 6 - vi lägger till ett objekt att kollidera med

    Nu vet vi hur vi skapar texturer, ritar ut dem på skärmen. Därför kommer jag snabbt skapa ett till objekt att kollidera med.

    Jag kommer inte att förklara denna kod då jag i princip kopierar delar av det jag gjort innan.

    Kod med fungerande collision detection mellan användare och objekt:

    Vår turtorial class ser nu ut så här:

    Kod:
    
    package com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    import com.badlogic.gdx.math.Vector3;
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild, objekt_bild;
    float scrw = 1280, scrh = 720;
    float OBJECT_X = scrw / 2 - 50 , OBJECT_Y = scrh / 2 - 50 ; // kordinater för objektet vi ska kollidera med. Vi anger dess kordinater till mitten av skärmen
    
    boolean COLLIDED = false;
    
    OrthographicCamera camera;
    
    Vector3 cords; // vector att lagra våra nya korrigerade cordinater från touch imput
    
    // deklarera ett objektet vi ska använda för collision detection
    collision_detection COLLISION;
    
    @Override
    public void create () {
    
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    objekt_bild = new Texture("objekt2.png"); // skapa vårt textur objekt
    
    // skapa en ortographic camera & sätt dess width & height till den upplösning vi vill ha
    camera = new OrthographicCamera();
    camera.viewportHeight = scrh;
    camera.viewportWidth = scrw;
    
    cords = new Vector3(); // skapa vectorn för input
    
    COLLISION = new collision_detection(); // skapa objekt av klassen collision_detection
    }
    
    @Override
    public void render () {
    
    Gdx.gl.glClearColor(0, 0, 0, 0); // ange svart bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
    camera.update();
    
    input(); // anropa vår metod för input
    
    COLLIDED = COLLISION.check_collision(cords, OBJECT_X, OBJECT_Y); // kolla om kollision sker
    
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined);
    vår_batch.draw(vår_bild, cords.x, cords.y); // visa vår bild på skärmen
    vår_batch.draw(objekt_bild, OBJECT_X, OBJECT_Y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    cords = new Vector3(Gdx.input.getX()-50 , Gdx.input.getY()+50, 0);
    camera.unproject(cords);
    }
    }
    
    
    Vår collision_Detection klass ser nu ut så här:

    Kod:
    
    public class collision_detection {
    
    // deklarering
    Rectangle Object_rectangle;
    Rectangle Player_rectangle;
    
    //skapa
    collision_detection(){
    
    // skapa våra rektanglar
    Object_rectangle = new Rectangle();
    Player_rectangle = new Rectangle();
    
    // Ange bredd på rektanglar
    Object_rectangle.width = 100;
    Object_rectangle.height = 100;
    Player_rectangle.width = 100;
    Player_rectangle.height = 100;
    }
    
    public boolean check_collision(Vector3 cords_player, float object_X, float object_Y){
    
    // Applicera våra uppdaterade kordinater på spelare samt det  objekt som vi ska kollidera med
    Player_rectangle.x = cords_player.x; Player_rectangle.y = cords_player.y;
    Object_rectangle.x = object_X; Object_rectangle.y = object_Y;
    
    //användare, objekt
    float leftA, leftB;
    float rightA, rightB;
    float topA, topB;
    float bottomA, bottomB;
    
    boolean check = false;
    
    // Beräkna sidor för Spelare
    leftA = Player_rectangle.x;
    rightA = Player_rectangle.x + Player_rectangle.width;
    topA = Player_rectangle.y + Player_rectangle.height;
    bottomA = Player_rectangle.y;
    
    //Beräkna sidor för objektet
    leftB = Object_rectangle.x;
    rightB = Object_rectangle.x + Object_rectangle.width;
    topB = Object_rectangle.y + Object_rectangle.height;
    bottomB = Object_rectangle.y;
    // kolla om en sida överskrider en sida av objekt. Om så är fallet har en kollision skett!
    
    if (topA >= bottomB && bottomA <= topB && rightA >= leftB && leftA <= rightB)
    {
    check = true;
    Gdx.app.exit();
    }
    
    return check;
    }
    
    }
    
    
    Det som händer vid kollision är att programmet avslutas med kommandot Gdx.app.exit();

    Här har vi nu ett helt fungerande "spel" ovan!

    RESULTAT:



    Vi i princip med alla huvudfunktioner för ett spel & det enda som fattas är att bygga på spelet.

    Med dessa grunder är det i princip bara kopiera, och klistra in. Då allt bygger på samma princip!

    Det man vill göra för att få ett lite roligare spel är att t.e.x. lägga till hur objekten ska uppföra sig. D.v.s. om dom ska röra sig, hoppa, studsa, snurra osv...

    Kopiera gärna senaste koden ovan d.v.s. koden från klassen turtorial & koden från klassen collsision detection!

    Nu går vi över till enklare saker!


    ----------------------------------------------------------------------------------

    6.0 - Musik & ljudeffekter
    I detta kapitel lägger vi till musik & ljudeffekter! Jag kommer att gå igenom detta kapitel fort, då jag inte tror att jag behöver förklara det jag gör.


    Steg 1 - skapa en ny Java klass & döp den till sounds

    Gör en konstruktor för den nya klassen:

    Kod:
    
    package com.turtorial.game;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.audio.Music;
    import com.badlogic.gdx.audio.Sound;
    import com.badlogic.gdx.files.FileHandle;
    /**
    * Created by GoseTech2 on 2015-12-20.
    */
    
    public class sounds {
    
    // deklarera ljudeffekter & musik
    public Sound VÅR_LJUDEFFEKT;
    public Music VÅR_MUSIK;
    
    sounds(){
    
    // ladda in effekter
    VÅR_LJUDEFFEKT = Gdx.audio.newSound(Gdx.files.internal("ljudeffekt.wav"));
    
    VÅR_MUSIK = Gdx.audio.newMusic(Gdx.files.internal("musik.wav"));
    }
    }
    
    
    För att spela upp musiken deklarerar vi & skapar ett objekt för vår nya klass(objektet deklareras ovanför create & skapas inom metoden create, detta i vår felstavade turtorial_class:()

    Deklarera:
    Kod:
    
    public class turtorial_class extends ApplicationAdapter {
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild, objekt_bild;
    
    // Deklarera objekt för hantering av ljud
    sounds playsound;
    
    float scrw = 1280, scrh = 720;
    
    ...
    
    
    Ovan har vi deklarerat vårat objekt för ljudhantering

    Skapa sedan vårat objekt för hantering av ljud:

    Kod:
    
    public void create () {
    
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    objekt_bild = new Texture("objekt2.png"); // skapa vårt textur objekt
    
    // skapa en ortographic camera & sätt dess width & height till den upplösning vi vill ha
    camera = new OrthographicCamera();
    camera.viewportHeight = scrh;
    camera.viewportWidth = scrw;
    
    cords = new Vector3(); // skapa vectorn för input
    
    COLLISION = new collision_detection();
    
    // skapa objekt för hantering av ljud
    playsound = new sounds();
    
    
    Ovan har vi skapat vårat objekt genom att lägga till följande i metoden create: playsound = new sounds();

    Vi spelar sedan upp ljuden såhär(vartsomhelst ifrån vår turtorial_class:(

    Kod:
    public void render () {
    
    Gdx.gl.glClearColor(0, 0, 0, 0); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
    camera.update();
    
    input(); // anropa vår metod för input
    
    COLLIDED = COLLISION.check_collision(cords, OBJECT_X, OBJECT_Y); // kolla om kollision sker
    
    if(COLLIDED){
    playsound.VÅR_LJUDEFFEKT.play();
    }
    

    Ovan spelar vi upp vår ljudeffekt genom: playsound.VÅR_LJUDEFFEKT.play();

    Man spelar även upp musik likadant.





    ---------------------------------------------------------------------------------------------------


     
    Last edited: 20 dec 2015
    chucken och Dez gillar detta.
  6. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    7.0 - All kod & nedladdningslänk till projektet

    Denna tutorial är nu klar för stunden!

    Vi har i denna guide lärt oss:
    • Hantera input
    • Flytta texturer med fingret
    • Skala spelet på alla skärmstorlekar
    • Hur collision detection fungerar
    • spela upp ljudeffekter & musik
    Med detta avklarat är det enkelt att fortsätta bygga ett spel. Med allt jag gått igenom så kan man skapa i princip vilket 2D spel som helst!

    Allt bygger på ovanstående moment!

    All kod för denna tutorial finner ni nedan! Det är bara att kopiera & klistra in!

    Klassen turtorial_class:
    Kod:
    ackage com.turtorial.game;
    import com.badlogic.gdx.ApplicationAdapter;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL20;
    import com.badlogic.gdx.graphics.OrthographicCamera;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    import com.badlogic.gdx.math.Vector3;
    
    public class turtorial_class extends ApplicationAdapter {
    
    // deklarera objekt
    SpriteBatch vår_batch;
    Texture vår_bild, objekt_bild;
    
    // Deklarera objekt för hantering av ljud
    sounds playsound;
    
    float scrw = 1280, scrh = 720;
    
    float OBJECT_X = scrw / 2 - 50 , OBJECT_Y = scrh / 2 - 50 ; // kordinater för objektet vi ska kollidera med. Vi anger dess kordinater till mitten av skärmen
    
    boolean COLLIDED = false;
    
    OrthographicCamera camera;
    
    Vector3 cords; // vector att lagra våra nya korrigerade cordinater från touch imput
    
    // deklarera ett objektet vi ska använda för collision detection
    collision_detection COLLISION;
    
    @Override
    public void create () {
    
    vår_batch = new SpriteBatch(); // skapa vårt batch objekt
    vår_bild = new Texture("objekt1.png"); // skapa vårt textur objekt
    objekt_bild = new Texture("objekt2.png"); // skapa vårt textur objekt
    
    // skapa en ortographic camera & sätt dess width & height till den upplösning vi vill ha
    camera = new OrthographicCamera();
    camera.viewportHeight = scrh;
    camera.viewportWidth = scrw;
    
    cords = new Vector3(); // skapa vectorn för input
    
    COLLISION = new collision_detection();
    // skapa objekt för hantering av ljud
    playsound = new sounds();
    }
    
    @Override
    public void render () {
    Gdx.gl.glClearColor(0, 0, 0, 0); // ange röd bakgrund
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
    camera.update();
    
    input(); // anropa vår metod för input
    
    COLLIDED = COLLISION.check_collision(cords, OBJECT_X, OBJECT_Y); // kolla om kollision sker
    
    if(COLLIDED){
    playsound.VÅR_LJUDEFFEKT.play();
    }
    
    vår_batch.begin();
    vår_batch.setProjectionMatrix(camera.combined);
    vår_batch.draw(vår_bild, cords.x, cords.y); // visa vår bild på skärmen
    vår_batch.draw(objekt_bild, OBJECT_X, OBJECT_Y); // visa vår bild på skärmen
    vår_batch.end();
    }
    
    public void input(){
    
    // hämtar input från användaren & lagrar i variablerna X & Y som vi skapat tidigare
    cords = new Vector3(Gdx.input.getX()-50 , Gdx.input.getY()+50, 0);
    camera.unproject(cords);
    }
    }
    
    

    klassen collision_detection
    Kod:
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.math.Rectangle;
    import com.badlogic.gdx.math.Vector3;
    /**
    * Created by GoseTech2 on 2015-12-19.
    */
    public class collision_detection {
    
    // deklarering
    Rectangle Object_rectangle;
    Rectangle Player_rectangle;
    
    //skapa
    collision_detection(){
    
    // skapa våra rektanglar
    Object_rectangle = new Rectangle();
    Player_rectangle = new Rectangle();
    
    // Ange bredd på rektanglar
    Object_rectangle.width = 100;
    Object_rectangle.height = 100;
    
    Player_rectangle.width = 100;
    Player_rectangle.height = 100;
    }
    
    public boolean check_collision(Vector3 cords_player, float object_X, float object_Y){
    
    // Applicera våra uppdaterade kordinater på vårt objekt som vi ska kollidera med
    Player_rectangle.x = cords_player.x; Player_rectangle.y = cords_player.y;
    Object_rectangle.x = object_X; Object_rectangle.y = object_Y;
    
    // Skapar lite onödiga vraibler för att det ska bli lättare att förstå
    //användare, objekt
    float leftA, leftB;
    float rightA, rightB;
    float topA, topB;
    float bottomA, bottomB;
    
    boolean check = false;
    
    // Beräkna sidor för Spelare
    leftA = Player_rectangle.x;
    rightA = Player_rectangle.x + Player_rectangle.width;
    topA = Player_rectangle.y + Player_rectangle.height;
    bottomA = Player_rectangle.y;
    
    //Beräkna sidor för objektet
    leftB = Object_rectangle.x;
    rightB = Object_rectangle.x + Object_rectangle.width;
    topB = Object_rectangle.y + Object_rectangle.height;
    bottomB = Object_rectangle.y;
    
    // kolla om en sida överskrider en sida av objekt. Om så är fallet har en kollision skett!
    if (topA >= bottomB && bottomA <= topB && rightA >= leftB && leftA <= rightB)
    {
    
    check = true;
    Gdx.app.exit();
    
    }
    
    return check;
    
    }
    
    }
    
    

    Klassen sounds
    Kod:
    
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.audio.Music;
    import com.badlogic.gdx.audio.Sound;
    import com.badlogic.gdx.files.FileHandle;
    /**
    * Created by GoseTech2 on 2015-12-20.
    */
    public class sounds {
    
    // deklarera ljudeffekter & musik
    public Sound VÅR_LJUDEFFEKT;
    public Music VÅR_MUSIK;
    
    sounds(){
    
    // ladda in ljudeffekter & musik
    VÅR_LJUDEFFEKT = Gdx.audio.newSound(Gdx.files.internal("ljudeffekt.wav"));
    VÅR_MUSIK = Gdx.audio.newMusic(Gdx.files.internal("musik.wav"));
    
    }
    }
    
    

     
    Last edited: 21 dec 2015
  7. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    8.0 Integrering av Google Admob - Visa annonser & tjäna pengar!
    Efter jobb & slit är det dags att tjäna pengar! Vi väljer att använda oss av Google Admob!

    OBS!
    Guiden för annonser är tagen från http://www.norakomi.com/tutorial_admob_part1.php#scroll_setting_up_admob
    Jag översätter den endast till svenska!

    Steg 1 - skapa ett konto hos Admob via denna länk: https://www.google.com/admob/

    1. När du väl gjort ett konto hos Admob, så trycker du på monetize -> monetize a new app
    2. Konfigurera annonsen & Välj banner som format
    3. Skriv ner din annons ID: ser ut såhär(Ad unit ID: ca-app-pub-5619007672210191/12375xxxx)
      Denna Ad ID lägger vi senare till i vårat spel för att verifiera att just din app visar annonsen & att det är du som ska ha pengarna för eventuella klick.
    Steg 2 - Konfigurera SDK

    Det är dags att börja koda igen! Detta är nog det svåraste momentet i denna tutorial. Har man dock gjort det en gång så är det i princip bara att kopiera till framtida projekt!

    Notera! Detta är inte bundet till LibGDX på något sätt. Utan kan användas till alla möjliga bibliotek.

    Innan vi börjar att koda måste vi lägga till Google Play Services i vårat projekt!

    Öpnna Android studio & ditt projekt.

    Öppna sedan SDK Manager & gör följande:

    1. Tryck på tools i Android Studio -> Android -> SDK Manager
    2. Markera Google Play services & Google Repository
    3. Tryck på installera
    Det kan ta ett tag att ladda ner filerna. Vänta tills allt är klart & installerat. Ett tips är att gå & brygga lite kaffe!


    Steg 3 - Konfigurera vår AndroidManifest.xml fil

    Öppna ditt projekt i Android Studio.

    Navigera sedan till din AndroidManifest.xml fil som du når i menyn till vänster. Se bild nedan:
    [​IMG]


    Kod:
    
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.turtorial.game.android"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />
    
        <application
    
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/GdxTheme" >
            <activity
                android:name="com.turtorial.game.android.AndroidLauncher"
                android:label="@string/app_name"
                android:screenOrientation="landscape"
                android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    
    
    
    Vår xml fil ser ut som ovan omodifierad:

    Ändra först minSdkVersion till 9!


    Kod:
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    
    Lägg till ovanstående kod ovanför <application>.


    Kod:
    
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    
    <activity
        android:name="com.google.android.gms.ads.AdActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
    
    Lägg sedan till ovanstående kod inom <application>

    Då var vi klara med vår manifest fil!


    Steg 4 - Skapa ett interface & lägg till metoder för annonshantering

    Skapa ett interface genom att högercklicka på ditt "package"(com.turtorial.game).

    OBS! DITT INTERFACE SKA SKAPAS FÖR DIN SPEL KLASS(INTERFACET SKA LIGGA INOM CORE/JAVA/DITT_PACKAGE)
    1. Högerklicka på ditt "package".
    2. klicka på new -> Java Class
    3. I listan som kommer upp väljer du interface
    4. Döp ditt interface till annonshanterare

    Nu har vi skapat ett interface. Nästa steg blir att lägga till 2 metoder för hantering av våra annonser.

    Deklarera 2 metoder i ditt interface så det ser ut som nedan:
    Kod:
    
    package com.turtorial.game.android;
    
    /**
    * Created by GoseTech2 on 2016-01-05.
    */
    public interface annonshanterare {
    
        void visa_annonser();
        void dölj_annonser();
    
    }
    
    

    Gå sedan till din Android Launcher klass och implementera ditt interface:


    vi ändrar:
    Kod:
    public class AndroidLauncher extends AndroidApplication{....}
    
    till:
    Kod:
    public class AndroidLauncher extends AndroidApplication implements annonshanterare{....}
    

    Kod:
    public class AndroidLauncher extends AndroidApplication implements annonshanterare {
       @Override
       protected void onCreate (Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
          initialize(new turtorial_class(), config);
       }
    }
    

    Vi har implementerat vårt interface & din launcher bör nu se ut som ovan.

    Gör nu följande:

    1. Markera nu din Android Launcher klass & tryck på CTRL + I.
    2. Markera Metoderna (visa_annonser, dölj_annonser) & tryck på ok.
    Om allt gick bra så bör din Android Launcher nu se ut såhär:
    Kod:
    
    public class AndroidLauncher extends AndroidApplication implements annonshanterare {
       @Override
       protected void onCreate (Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
          initialize(new turtorial_class(), config);
       }
    
       @Override
       public void visa_annonser() {
    
       }
    
       @Override
       public void dölj_annonser() {
    
       }
    }
    
    


    Steg 5 - Konfigurera våra metoder för annonshantering.

    Nu är vi snart klara! Det enda som fattas är att få våra metoder att faktiskt göra något!

    Vi börjar med att skapa innehållet i vår visa_annonser metod. Lägg till följande kod inom metoden visa_annonser:
    Kod:
    
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    bannerAd.setVisibility(View.VISIBLE);
    AdRequest.Builder builder = new AdRequest.Builder();
    AdRequest ad = builder.build();
    bannerAd.loadAd(ad);
    }
    });
    
    

    och följande i vår metod dölj_annonser:

    Kod:
    
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    bannerAd.setVisibility(View.INVISIBLE);
    }
    });
    
    
    Nu är vi klara med våra metoder för hantering av annonser!

    Steg 6 - Skapa En Layout för våra annonser!
    Detta borde jag ha gjort innan! Men det spelar ingen roll. Vi ska nu skapa en Layout för våra annonser. D.v.s. hur dom ska se ut.

    Deklarera ett objekt för får layout, annons:

    Kod:
    
    public class AndroidLauncher extends AndroidApplication implements annonshanterare {
    
       AdView bannerAd;
    
    
    Lägg sedan till följande kod i konstruktorn(vi arbetar fortfarande i Android launcher klassen:(

    Kod:
    
    RelativeLayout layout = new RelativeLayout(this);
    layout.addView(gameView, ViewGroup.LayoutParams.MATCH_PARENT,
          ViewGroup.LayoutParams.MATCH_PARENT);
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
          ViewGroup.LayoutParams.MATCH_PARENT,
          ViewGroup.LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    layout.addView(bannerAd, params);
    
    setContentView(layout);
    
    
    Skapa sedan en ny metod i din launcher klass. Döp den till setupAds och lägg till följande kod:

    Kod:
    
    public void setupAds() {
       bannerAd = new AdView(this);
       bannerAd.setVisibility(View.INVISIBLE);
       bannerAd.setBackgroundColor(0xff000000); // black
       bannerAd.setAdUnitId(ANNONS_ID);
       bannerAd.setAdSize(AdSize.SMART_BANNER);
    }
    
    
    metoden ovan skapar ett objekt för vår annons.

    Anropa metoden vi skapade ovan:
    Kod:
    
    @Override
    protected void onCreate (Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
    
       View gameView = initializeForView(new turtorial_class(), config);
    
       setupAds(); // anropa metoden som skapar vår annonslayout
    
    
    Lägg till en sträng som fält som ska hålla din annons ID:

    Kod:
    
    public class AndroidLauncher extends AndroidApplication implements annonshanterare {
    
       AdView bannerAd;
    
       private static final String ANNONS_ID ="DINANNONSID";
    
    

    Steg 7 - Visa annonsen i ditt spel!
    Det enda som återstår är att visa annonserna i ditt spel.

    Innan vi kan göra det måste vi först modifiera vår turtorial_class en aning:

    Lägg till följande kod ovanför metoden create i din turtorial_class:

    Kod:
    
    annonshanterare kontrollera;
    
    public turtorial_class(annonshanterare kontrollera){
       this.kontrollera = kontrollera;
    }
    
    
    Nu kan vi visa och dölja våra annonser genom att skriva:


    Visa annonser:

    Kod:
    
    kontrollera.visa_annonser();
    
    
    ovan anropar vi metoden visa_annonser för att visa annonser!

    Dölj annonser:

    Kod:
    
    kontrollera.dölj_annonser();
    

    Var du anropar metoderna ifrån spelar ingen roll, så länge du gör det från din turtorial_class.


    Steg 8 - All kod

    Och med det är denna del av guiden klar!

    Jag avslutar med att posta all kod:

    AndroidManifest.xml:
    Kod:
    
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.turtorial.game.android"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23" />
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
        <application
    
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/GdxTheme" >
            <activity
                android:name="com.turtorial.game.android.AndroidLauncher"
                android:label="@string/app_name"
                android:screenOrientation="landscape"
                android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <meta-data
                android:name="com.google.android.gms.version"
                android:value="@integer/google_play_services_version" />
    
            <activity
                android:name="com.google.android.gms.ads.AdActivity"
                android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
    
        </application>
    
    </manifest>
    
    
    AndroidLauncher:

    Kod:
    
    package com.turtorial.game.android;
    
    import android.os.Bundle;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.RelativeLayout;
    
    import com.badlogic.gdx.backends.android.AndroidApplication;
    import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
    import com.google.android.gms.ads.AdRequest;
    import com.google.android.gms.ads.AdSize;
    import com.google.android.gms.ads.AdView;
    import com.turtorial.game.annonshanterare;
    import com.turtorial.game.turtorial_class;
    
    public class AndroidLauncher extends AndroidApplication implements annonshanterare {
    
       AdView bannerAd;
    
       private static final String ANNONS_ID ="DINANNONSID";
    
       @Override
       protected void onCreate (Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
    
          View gameView = initializeForView(new turtorial_class(this), config);
    
          setupAds();
    
          // Define the layout
          RelativeLayout layout = new RelativeLayout(this);
          layout.addView(gameView, ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
          RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
          params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
          layout.addView(bannerAd, params);
    
          setContentView(layout);
       }
    
       public void setupAds() {
          bannerAd = new AdView(this);
          bannerAd.setVisibility(View.INVISIBLE);
          bannerAd.setBackgroundColor(0xff000000); // black
          bannerAd.setAdUnitId(ANNONS_ID);
          bannerAd.setAdSize(AdSize.SMART_BANNER);
       }
    
       @Override
       public void visa_annonser() {
    
          runOnUiThread(new Runnable() {
             @Override
             public void run() {
                bannerAd.setVisibility(View.VISIBLE);
                AdRequest.Builder builder = new AdRequest.Builder();
                AdRequest ad = builder.build();
                bannerAd.loadAd(ad);
             }
          });
       }
    
       @Override
       public void dölj_annonser() {
    
          runOnUiThread(new Runnable() {
             @Override
             public void run() {
                bannerAd.setVisibility(View.INVISIBLE);
             }
          });
       }
    }
    
    
    Vårat Interface(annonshanterare)
    Kod:
    
    public interface annonshanterare {
    
        void visa_annonser();
        void dölj_annonser();
    
    }
    
    

    Ställ gärna frågor!






     
    Last edited: 6 jan 2016
    RuffyMan gillar detta.
  8. Ero

    Ero Teen Droid Medlem

    Blev medlem:
    6 jan 2011
    Inlägg:
    302
    Mottagna gillanden:
    48
    Operatör:
    Telia
    Telefon:
    iPhone XS

    MINA ENHETER

    Operatör:
    Telia
    Telefon:
    iPhone XS
    Info:
    Jobbtelefon
    Supernice! Önska jag hade tiden att sätta mig in i detta! Får bli på semestern till sommar :eek:

    Praktisk fråga bara:

    Kod:
    public interface annonshanterare {
    
        void visa_annonser();
        void dölj_annonser();
    
    }
    Kod:
    annonshanterare kontrollera;
    annonshanterare borde bli Annonshanterare eftersom det är ett interface och sen bör den väl inte heta kontrollera, utan annonshanterare? Antar att du inte döpte till annonshanterare eftersom interfacet hette lika?

    Gillar även att du använder dig av svenska variabel- och metodnamn! "Githubba" detta så kanske flera kan hjälpa till att döpa om alla variabler och metoder till svenska så barn lättare förstår vad dom gör (även om kommentarer oftast hjälper, så underlättar det nog).
     
  9. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER



    Det är sant! Annonshanterare borde det vara. Vet inte hur jag tänkte. Gjorde den sista delen av guiden ganska snabbt!

    Ser även att jag blandat engelska & svenska(är van att köra allt på engelska). Ska gå igenom guiden när jag har tid & förbättra, ändra små fel.

    T.ex. rekommenderar jag att använda LibGDX inbyggda klass för kollision. Spar tid & fungerar på samma sätt! Men ville visa hur det fungerar!

    Sen så har jag glömt en till viktig del. Hur man använder Fonts. Det får läggas till senare :).
     
  10. Oggie

    Oggie Kid Droid Medlem

    Blev medlem:
    14 jan 2011
    Inlägg:
    61
    Mottagna gillanden:
    28
    Operatör:
    Comviq
    Telefon:
    Samsung S20 FE 5G

    MINA ENHETER

    Operatör:
    Comviq
    Telefon:
    Samsung S20 FE 5G
    Tack för din guide och att du tar dig tid att göra den.
    Jag håller på med en guide från kilobolt just nu men tänker helt klart att gå genom också.
    Bra att läsa, testa, fundera och lära mig nytt inför att jag ska koda själv :).
     
  11. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Tycker det endast är kul att hjälpa! Hoppas den är till hjälp!

    Håller själv på med ett nytt mobilspel, där jag kämpat med dynamiskt vatten under några veckor nu som börjar se riktigt bra ut :)
     
  12. bernard

    bernard Droidmin Moderator

    Blev medlem:
    14 maj 2009
    Inlägg:
    40 629
    Mottagna gillanden:
    44 565
    Operatör:
    Tre+Fello
    Telefon:
    Pixel 7 Pro+iPhone 13 mini

    MINA ENHETER

    Operatör:
    Tre+Fello
    Telefon:
    Pixel 7 Pro+iPhone 13 mini
    ROM:
    Stock
    Platta:
    Watch Series 7
    Övrigt:
    Huawei Watch GT (2019)
  13. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

  14. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Då var jag live ännu en gång. För den som vill chilla och kolla lite(swengelska) :)
    Utvecklar vårat senaste spel som faktiskt har fått väldigt bra respons! Finns att ladda ner här: www.maseapps.com

    www.Twitch.com/maosk21
     
    bernard gillar detta.
  15. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Twitch

    Igen.... Tog bort alla andra streamposts.

    Kanske ska sluta spamma denna tråd. Men känns ändå som jag har rättigheten då jag skapat den :D
     
    bernard gillar detta.
  16. Casnova

    Casnova Infant Droid Medlem

    Blev medlem:
    9 jan 2019
    Inlägg:
    2
    Mottagna gillanden:
    0

    MINA ENHETER

    Hej

    Är också intresserad och vill lära mig, men ser väldigt avancerad ut. Tänkte börja kanske med Defold och LUA. Du har inspirerat mig, tack.
     
  17. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Alltid kul att inspirerar :)

    Inte jätte avancerat, men såklart. Tar ju ett tag att bli bekväm..

    Kör en liten stream nu med!
    Twitch
    (börjar faktsikt bli klar)!

    Kom och snacka!
     
  18. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Twitch

    Kör lite Live stream igen för de som är intresserade eller har frågor!
     
  19. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Lite fredagslive med Whiskey!

    Kom och mys!

    Twitch
     
  20. maosk21

    maosk21 Kid Droid Medlem

    Blev medlem:
    2 sept 2015
    Inlägg:
    39
    Mottagna gillanden:
    22

    MINA ENHETER

    Vi kör lite LIVE nu när jag färdigställer vårat senaste lir "Swinging Zoo" Kom & kolla vet ja! ?

    Twitch