Kamis, 25 Juni 2015

Pengantar Teknologi Game #3

Nama : Marihot Kaisar
NPM : 54412439
Kelas : 3IA24




BREAKOUT GAME

      1.      TAHAP KEBUTUHAN
      1.1.Eclipse
Eclipse adalah sebuah IDE (Integrated Development Environment) untuk mengembangkan perangkat lunak dan dapat dijalankan di semua platform (platform-independent).
(Sumber : http://id.wikipedia.org/wiki/Eclipse_(perangkat_lunak) )

      1.2.JRE dan JDK, dan pengertiannya disini
Seperti namanya, JDK adalah semacam kotak peralatan (kit) yang digunakan untuk development. JDK ini berguna saat Anda menulis code program. Seperti halnya JRE, JDK juga memiliki JVM di dalamnya.
JRE adalah sesuatu yang memungkinkan sebuah program Java dapat berjalan di mesin Anda. JRE ini mengeksekusi binary-binary dari class-class dan mengirimnya ke JVM untuk diproses lagi ke prosesor. Setiap JRE pasti memiliki sebuah JVM di dalamnya untuk melakukan pemrosesan selanjutnya.
(Sumber : https://webanggasurya.wordpress.com/2012/10/16/perbedan-jdk-dan-jre-pada-java/ )

      1.3.Android SDK
Android-SDK merupakan tools bagi para programmer yang ingin mengembangkan aplikasi berbasis google android. Android SDK mencakup seperangkat alat pengembangan yang komprehensif. Android SDK terdiri dari debugger, libraries, handset emulator,dokumentasi, contoh kode, dan tutorial.
(Sumber : https://haidibarasa.wordpress.com/2013/07/06/pengertian-android-sdk-software-development-kit/ )

      1.4.Smart Phone berbasis Android
Android adalah sistem operasi berbasis Linux yang dirancang untuk perangkat seluler layar sentuh seperti telepon pintar dan komputer tablet. Android awalnya dikembangkan oleh Android, Inc., dengan dukungan finansial dari Google, yang kemudian membelinya pada tahun 2005. Sistem operasi ini dirilis secara resmi pada tahun 2007, bersamaan dengan didirikannya Open Handset Alliance, konsorsium dari perusahaan-perusahaan perangkat keras, perangkat lunak, dan telekomunikasi yang bertujuan untuk memajukan standar terbuka perangkat seluler. Ponsel Android pertama mulai dijual pada bulan Oktober 2008.
(Sumber : http://id.wikipedia.org/wiki/Android_(sistem_operasi) )

      2.      TAHAP DOWNLOAD
      2.1.Download Eclipse
Anda dapat mendownload Eclipse disini.

      2.2.Download JRE dan JDK disini
Anda dapat mendownload JRE dan JDK disini.

      2.3.Download Android SDK disini
Anda dapat mendownload Android SDK disini.

      3.      TAHAP PENGINSTALAN
      3.1.JRE dan JDK
JRE dan JDK dapat anda dilihat tahapan penginstalan disini.

      3.2.Android SDK.
Android SDK dapat anda dilihat tahapan penginstalan disini.

      3.3.Eclipse
Eclipse tidak perlu diinstal hanya perlu di ekstrak file nya.

     4.      TAHAP KODING
     4.1.Source Code

     a.       MainActivity.java
                 package com.kaisar.breakoutgame;

                 import com.kaisar.breakoutgame.R;

                 import android.app.Activity;
                 import android.os.Bundle;
                 import android.util.Log;
                 import android.view.Menu;
                 import android.view.MenuItem;
                 import android.widget.TextView;
    
                  public class MainActivity extends Activity implements BreakoutBoardCallback {

                  private static final String TAG = "MainActivity";
                  private BreakoutBoardView board;
                  private TextView lives;

     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lives = (TextView) findViewById(R.id.lives);
        board = (BreakoutBoardView) findViewById(R.id.gameboard);
        board.setCallback(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_reset:
            Log.d(TAG, "Resetting game");
            board.getThread().reset();
            break;
        }
        return false;
    }

    @Override
    public void onGameChanged(final int nbrOfLivesLeft) {
        // Make sure we run on UI thread
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                String label = String.format(getResources().getString(R.string.lives), nbrOfLivesLeft);
                lives.setText(label);
            }
        });
    }

    @Override
    public void onGameFinished() {
        // do nothing (for now)
    }
}
      b. BreakoutBoardCallback.java
package com.kaisar.breakoutgame;

public interface BreakoutBoardCallback {
    public void onGameChanged(int nbrOfLivesLeft);
    public void onGameFinished();
}

      c. BreakoutBoardView.java
        package com.kaisar.breakoutgame;

import java.util.ArrayList;
import java.util.Iterator;
        import java.util.List;

        import com.kaisar.breakoutgame.model.Background;
        import com.kaisar.breakoutgame.model.Block;
        import com.kaisar.breakoutgame.model.Dot;
        import com.kaisar.breakoutgame.model.Entity;
        import com.kaisar.breakoutgame.model.Paddle;

       import android.content.Context;
       import android.graphics.Canvas;
       import android.graphics.Paint;
       import android.util.AttributeSet;
       import android.util.Log;
       import android.view.MotionEvent;
       import android.view.SurfaceHolder;
       import android.view.SurfaceView;
       import android.view.View;
       import android.view.View.OnTouchListener;

      public class BreakoutBoardView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener {

     private static final String TAG = "BreakoutBoardView";

    // Render thread
     private BreakoutBoardThread thread;
   
    // Touch event position for the paddle
     private double lastKnownPaddlePosition;
     private BreakoutBoardCallback callback;

     public BreakoutBoardView(Context context, AttributeSet attrs) {
        super(context, attrs);

        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        // SurfaceView must have focus to get touch events
        setFocusable(true);
        setOnTouchListener(this);
    }

     public void setCallback(BreakoutBoardCallback callback) {
        this.callback = callback;
    }

     @Override
     public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "Surface created, starting new thread...");
        thread = new BreakoutBoardThread(holder);
        thread.setRunning(true);
        thread.start();
    }

     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.d(TAG, "Surface changed, resetting game...");
        thread.setSurfaceSize(width, height);
    }

     @Override
     public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(TAG, "Surface destroyed, trying to shut down thread...");
        boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
                // Do nothing
            }
        }
        Log.d(TAG, "Thread's dead, baby. Thread's dead.");
    }

     @Override
     public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                lastKnownPaddlePosition = event.getX();
        }
        return true;
    }

     public BreakoutBoardThread getThread() {
        return thread;
    }
 
        class BreakoutBoardThread extends Thread {

        // Debug
        private static final String TAG = "BreakoutBoardThread";
       
        // Game constants
        private static final int NBR_OF_BLOCKS = 6;
        private static final double DOT_SPEED = 400.0;
        private static final int NBR_OF_LIVES = 3;

        // Game variables
        private int nbrOfTriesLeft;
        private long lastTime;

        // Draw stuff
        private SurfaceHolder surfaceHolder;
        private boolean running;
        private int canvasWidth;
        private int canvasHeight;
        private Background background;

        // Entities
        private List gameEntities;
        private ArrayList blocks;
        private ArrayList destroyedBlocks;
        private Paddle paddle;
        private Dot dot;

        public BreakoutBoardThread(SurfaceHolder surfaceHolder) {
            this.surfaceHolder = surfaceHolder;
            restart();
        }

        public void setRunning(boolean running) {
            this.running = running;
        }

        private void dead() {
            Log.d(TAG, "Bang! You're dead. Resetting...");
            reset();
            BreakoutBoardView.this.callback.onGameChanged(--nbrOfTriesLeft);
            if (nbrOfTriesLeft <= 0) {
                setRunning(false);
                BreakoutBoardView.this.callback.onGameFinished();
            }
        }

        public void restart() {
            reset();
            nbrOfTriesLeft = NBR_OF_LIVES;
            BreakoutBoardView.this.callback.onGameChanged(nbrOfTriesLeft);
        }

        public void reset() {
            synchronized (surfaceHolder) {
                resetEntities(canvasWidth, canvasHeight);
            }
        }

        @Override
        public void run() {
            while (running) {
                Canvas c = null;
                try {
                    c = surfaceHolder.lockCanvas(null);
                    synchronized (surfaceHolder) {
                        updatePhysics();
                        // NOTE: In newer versions of Android (4+), it seems SurfaceHolder.lockCanvas() may return null whenever
                        // SurfaceHolder.Callback.surfaceDestroyed() has been invoked. In earlier versions, a canvas was always
                        // returned until SurfaceHolder.Callback.surfaceDestroyed() was FINISHED. See bug report:
                        // https://code.google.com/p/android/issues/detail?id=38658
                        if (c != null) {
                            doDraw(c);
                        }
                    }
                } finally {
                    // do this in a finally so that if an exception is thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        surfaceHolder.unlockCanvasAndPost(c);
                    }
                }
            }
        }

        public void setSurfaceSize(int width, int height) {
            synchronized (surfaceHolder) {
                canvasWidth = width;
                canvasHeight = height;
                restart();
            }
        }

        private void resetEntities(int width, int height) {
            background = new Background(width, height);
            gameEntities = new ArrayList();
            blocks = new ArrayList();
            destroyedBlocks = new ArrayList();
            double blockWidth = width / (1.1 * NBR_OF_BLOCKS + 0.1);
            double blockHeight = 0.1 * blockWidth;
            for (int i = 0; i < NBR_OF_BLOCKS; i++) {
                double blockX = i * (blockWidth + blockHeight) + blockHeight;
                double blockY = 2 * blockHeight;
                Block b = new Block((int) blockX, (int) blockY, (int) blockWidth, (int) blockHeight);
                blocks.add(b);
                gameEntities.add(b);
            }
           
            double paddleWidth = blockWidth * 2;
            double paddleHeight = blockHeight * 2;
            double paddleX = (width - paddleWidth) / 2;
            double paddleY = height - paddleHeight;
            paddle = new Paddle((int) paddleX, (int) paddleY, (int) paddleWidth, (int) paddleHeight);
            // TODO: Thread should not meddle with properties of the view. Refactor...
            lastKnownPaddlePosition = paddle.getX();
            gameEntities.add(paddle);

            double dotSide = blockHeight;
            double dotX = paddleX + (paddleWidth - dotSide) / 2;
            double dotY = paddleY - dotSide;
            double startAngle = Math.PI * Math.random() * 0.25; // Starting angle should be somewhat upwards
            Log.d(TAG, "seed:" + startAngle);
            double vx = DOT_SPEED * Math.sin(startAngle);
            double vy = -DOT_SPEED * Math.cos(startAngle);
            Log.d(TAG, "x:" + dotX + ", y:" + dotY + ", side:" + dotSide);
            Log.d(TAG, "vx:" + vx + ", vy:" + vy);
            dot = new Dot((int) dotX, (int) dotY, (int) dotSide, (int) dotSide, vx, vy);
            gameEntities.add(dot);
        }

        // Update game entities for next iteration
        private void updatePhysics() {
            long now = System.currentTimeMillis();

            // Make sure we don't update physics unnecessary often
            if (lastTime > now)
                return;

            double elapsed = (now - lastTime) / 1000.0;

            // Update paddle position
            paddle.move(lastKnownPaddlePosition);
           
            // Update dot position
            double dx = dot.getVx() * elapsed;
            double dy = dot.getVy() * elapsed;
            dot.move(dx, dy, dot.getVx(), dot.getVy());
           
            // Check if dot collides with paddle
            if (dot.isColliding(paddle)) {
                // New direction depends on where the dot hits the paddle
                int vx = dot.getCollidingAngle(paddle);
                dot.move(-dx, -dy, vx, -dot.getVy());
            }
           
            // Check if dot hits block
            Iterator iter = blocks.iterator();
            while (iter.hasNext()) {
                Block b = iter.next();
                if (dot.isColliding(b)) {
                    iter.remove();
                    gameEntities.remove(b);
                    destroyedBlocks.add(b);
                    dot.move(-dx, -dy, dot.getVx(), -dot.getVy());
                }
            }
           
            // Check if dot hits walls
            if (dot.getX() < 0 || dot.getX() > canvasWidth) {
                dot.move(-dx, -dy, -dot.getVx(), dot.getVy());
            }
            if (dot.getY() < 0) {
                dot.move(-dx, -dy, dot.getVx(), -dot.getVy());
            }
           
            // Check if game over
            if (dot.getY() > canvasHeight) {
                dead();
            }
           
            lastTime = now;
        }

        // Draws game entities on canvas. Must be run in
        private void doDraw(Canvas c) {
            renderBackground(c);
            renderEntities(c);
        }

        // Render the board background.
        private void renderBackground(Canvas c) {
            c.drawRect(background.getRect(), background.getPaint());
        }

        private void renderEntities(Canvas c) {
            for (Entity e : gameEntities) {
                c.drawRect(e.getRect(), e.getPaint());
                if (e instanceof Dot) {
                    Log.d(TAG, "drawing dot: " + dot.getRect().centerX() + ", " + dot.getRect().centerY());
                }
            }

            Iterator iter = destroyedBlocks.iterator();
            while (iter.hasNext()) {
                Block b = iter.next();
                Paint p = b.getPaint();
                p.setAlpha(p.getAlpha() - 5);
                c.drawRect(b.getRect(), p);
                if (p.getAlpha() == 0) {
                    iter.remove();
                }
            }
        }
    }
}
 
      d.Background.java
package com.kaisar.breakoutgame.model;

import android.graphics.Color;

public class Background extends Entity {
    public Background(int width, int height) {
        super(0,0, width, height, Color.BLACK);
    }
}

      e. Block.java
package com.kaisar.breakoutgame.model;

import android.graphics.Color;

public class Block extends Entity {

    public Block(int posX, int posY, int width, int height) {
        super(posX, posY, width, height, Color.RED);
    }
}


      f. Dot.java
package com.kaisar.breakoutgame.model;

import android.graphics.Color;

public class Dot extends MovableEntity {

    private double vx;
    private double vy;

    public Dot(int posX, int posY, int width, int height, double vx, double vy) {
        super(posX, posY, width, height, Color.WHITE);
        this.vx = vx;
        this.vy = vy;
    }
   
    public void move(double dx, double dy, double vx, double vy) {
        super.move(dx, dy);
        this.vx = vx;
        this.vy = vy;
    }
   
    public double getVx() {
        return vx;
    }
   
    public double getVy() {
        return vy;
    }
}

      g. Entity.java
          package com.kaisar.breakoutgame.model;

          import android.graphics.Paint;
          import android.graphics.Rect;

          public class Entity {

          private static final int ANGLE_MOD = 5;

          private Rect rect;
          private Paint paint;

          public Entity(int posX, int posY, int width, int height, int color) {
          rect = new Rect(posX, posY, posX + width, posY + height);
          paint = new Paint();
          paint.setColor(color);
          }

          public Rect getRect() {
          return rect;
         }

         public Paint getPaint() {
         return paint;
         }

         public boolean isColliding(Entity entity) {
         Rect other = entity.getRect();
         return rect.intersects(other.left, other.top, other.right, other.bottom);
         }

         public int getCollidingAngle(Entity entity) {
         Rect other = entity.getRect();
         return ANGLE_MOD * (rect.centerX() - other.centerX());
         }
}

          h.  MovebleEntity
  package com.kaisar.breakoutgame.model;

  public class MovableEntity extends Entity {

    private double centerX;
    private double centerY;

    public MovableEntity(int posX, int posY, int width, int height, int color) {
        super(posX, posY, width, height, color);
        centerX = getRect().centerX();
        centerY = getRect().centerY();
    }

    public double getX() {
        return centerX;
    }

    public double getY() {
        return centerY;
    }

    public void move(double dx, double dy) {
        centerX += dx;
        centerY += dy;
        // Correctly round the position of the entity
        int moveX = (int) (centerX - getRect().centerX());
        int moveY = (int) (centerY - getRect().centerY());
        getRect().offset(moveX, moveY);
    }
}
           i. Paddle
     
              package com.kaisar.breakoutgame.model;

     import android.graphics.Color;

     public class Paddle extends MovableEntity {

     public Paddle(int posX, int posY, int width, int height) {
        super(posX, posY, width, height, Color.BLUE);
     }
   
     public void move(double position) {
        double dx = position - getX();
        super.move(dx, 0);
     }
}

        j. Activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/lives"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/lives"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="@dimen/activity_vertical_margin"/>

    <com.kaisar.breakoutgame.BreakoutBoardView
        android:id="@+id/gameboard"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/lives"/>

</RelativeLayout>

        5.      TAHAP IMPLEMENTASI
        5.1.Instalasi APK 
 
       6.2.Contoh Permainan



                               
        Sumber : http://billmill.org/static/canvastutorial/index.html


Nb : maaf kalau masih ada kesalahan 

Tidak ada komentar:

Posting Komentar