• Tidak ada hasil yang ditemukan

4. IMPLEMENTASI SISTEM

N/A
N/A
Protected

Academic year: 2021

Membagikan "4. IMPLEMENTASI SISTEM"

Copied!
39
0
0

Teks penuh

(1)

4. IMPLEMENTASI SISTEM

Setelah proses desain selesai dilakukan, maka pada bab ini akan dibahas

bagaimana implementasi sistem kerja dari program perancangan dan pembuatan

aplikasi

Game Racing Android

3 Dimensi ini. Program ini dibuat dengan

menggunakan

software Eclipse

yang merupakan

software

yang digunakan dalam

pemrograman untuk aplikasi java dan Android.Selain itu dalam mempermudah

pemrograman digunakanlah

framework Libgdx

yang merupakan

framework

dengan

life cycle

yang mudah untuk dimengerti dan dikhususkan untuk

pemrograman

game

sehingga mengurangi waktu pemrograman yang lambat

dikarenakan pemrograman dengan cara biasa yang mengharuskan penggunaan

fungsi-fungsi yang memang belum diperuntukkan untuk pemrograman

game

.

Tabel 4.1. Daftar

class

Nama

class

Nomor dari segmen

class

Start

Menu

MenuBuy

MenuLoad

MenuMap

MenuOption

MenuPesawat

MyGame

Score

Tombol

ItemBonus

Pesawat

4.1.1.

4.2.1

4.2.2

4.2.3

4.2.4

4.2.5

4.2.6

4.2.7

4.2.8

4.3.1

4.3.2

4.3.3

(2)

Tabel 4.2. Daftar prosedur dan fungsi

Nama prosedur atau fungsi

Bagian

class

segmen

cekluncurbonusAI

naikturun

cektabrakpesawatdepan

jalanAI

jalanAI2

jalanAI3

setjalanpathAI

caripathuser

Pesawat

Pesawat

Pesawat

Pesawat

Pesawat

Pesawat

Pesawat

Pesawat

4.3.3.1

4.3.3.2

4.3.3.3

4.3.3.4

4.3.3.5

4.3.3.6

4.3.3.7

4.3.3.8

4.1.

Implementasi Class Extend Game

Class Extend Game

ini merupakan

main class

dari

framework Libgdx

dimana

class

ini meng

implement

ApplicationListener

dan menjadi pusat dari

class-class

yang lain yang ada dalam

project Libgdx

. Maka dari itu di

class

ini

akan dilakukan deklarasi

object

dari

file

suara serta variabel-variabel yang

nantinya dibutuhkan sebagai

properties

class lain.

Berikut merupakan segmen 4.1.1. yang merupakan isi

source code class

Start

:

Segmen 4.1.1.

Class Start

package com.libgdx; import java.io.DataInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import android.os.Environment; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.utils.GdxRuntimeException; public class Start extends Game

(3)

{

private Music[] bgm,effect; private float bgmvol = 0.5f; private float effectvol=0.5f; private String namauser; private int indexkendaraan; private int indexmap; private int money; private int indexlevel; private int ranking; private int jenismenuload; private int[] statuspesawat;

public void create() { indexlevel=1; indexmap=0; indexkendaraan=0; namauser="racer"; statuspesawat=new int[4]; statuspesawat[0]=1; for(int i=1;i<4;i++) { statuspesawat[i]=0; } money=0;

File sdDir = Environment.getExternalStorageDirectory(); String path = sdDir.getAbsolutePath() + "/LIBGDX/"; File sgDir = new File(path);

if (!sgDir.exists()) { sgDir.mkdirs(); try {

sgDir.createNewFile(); } catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace();

} }

else {

(4)

try {

FileHandle

audioFileHandle=Gdx.files.external("LIBGDX/volume");

InputStream fstream = audioFileHandle.read(); DataInputStream in = new DataInputStream(fstream); String strline; while((strline=in.readLine())!=null) { if(strline.startsWith("B")) {

String[] tokens = strline.split(" ");

bgmvol=Float.valueOf(tokens[1])/100 ; }

if(strline.startsWith("E")) {

String[] tokens = strline.split(" ");

effectvol=Float.valueOf(tokens[1])/100 ; }

}

in.close();

} catch (GdxRuntimeException ex) {

// TODO Auto-generated catch block String strline; strline="B "+Float.toString(bgmvol*100)+"\nE "+Float.toString(effectvol*100); OutputStreamWriter out=new OutputStreamWriter(Gdx.files.external("LIBGDX/volume").write(false)); try { out.write(strline); out.flush(); out.close(); } catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace();

}

} catch (IOException e) {

// TODO Auto-generated catch block e.printStackTrace();

(5)

} } bgm=new Music[3]; effect=new Music[3]; bgm[0]=Gdx.audio.newMusic(Gdx.files.internal("audio/oldschool.mid" )); bgm[0].setLooping(true); bgm[1]=Gdx.audio.newMusic(Gdx.files.internal("audio/c2.MP3")); bgm[1].setLooping(true); bgm[2]=Gdx.audio.newMusic(Gdx.files.internal("audio/c3.MP3")); bgm[2].setLooping(true); effect[0]=Gdx.audio.newMusic(Gdx.files.internal("audio/engine.wav" )); effect[0].setLooping(true); effect[1]=Gdx.audio.newMusic(Gdx.files.internal("audio/go1.wav")); effect[2]=Gdx.audio.newMusic(Gdx.files.internal("audio/last.wav")) ; bgm[0].play(); for(int i=0;i<3;i++) { bgm[i].setVolume(bgmvol); } for(int i=0;i<3;i++) { effect[i].setVolume(effectvol); } ranking=0; setScreen(new Menu(this,null,null,null)); } }

(6)

Pada

Class Start

ini berisi semua fungsi dan variabel yang digunakan untuk

menampung

profil user

serta pilihan-pilihannya di setiap

menu

nya nanti dan juga

pemanggilan semua

file audio

yang dibutuhkan dan pembuatan

file

untuk

setting

pada

memory external

apabila

user

baru pertama kali menjalankan

game

atau

menghapus isi

memory external

yang berisi

file game

ini. Lalu

class

ini akan

menetapkan

Class Menu

menjadi tampilan awal dengan fungsi

setScreen(new

Menu(this,null,null,null))

dengan

this

merupakan

Class Start

yang dikirimkan ke

tiap

class Screen

dan

null

sebagai isi dari parameter

constractor Class Menu

yang

mengindikasi sebelumnya berasal dari

Class

yang mana.

4.2.

Implementasi Class Implements Screen

Class

yang

meng

implements

Screen

ini

semacam

class

mini

ApplicationListeners

.

Class

ini memiliki fungsi

render(), pause(), resume(),

dan

resize()

selain itu fungsi

hide()

dan

show().

Ketika fungsi

setScreen(screen)

dipanggil maka fungsi

hide()

dari

screen

sekarang dipanggil dan

screen

yang baru

akan menjadi

screen

sekarang dan fungsi

show()

akan dipanggil, setelah itu fungsi

render()

akan dipanggil setiap

frame

dari

game

. Dalam class ini fungsi

dispose()

tidak akan dipanggil melainkan fungsi

hide()

yang akan dipanggil. Sehingga

proses dari

screen

sebelumnya akan tetap berjalan.

Berikut merupakan source code Class MenuOption dari segmen 4.2.5. :

Segmen 4.2.5.

Class MenuOption

package com.libgdx; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import android.util.Log; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Screen; import com.badlogic.gdx.files.FileHandle;

(7)

import com.badlogic.gdx.graphics.GL10;

import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.Texture;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class MenuOption implements Screen{ private int WIDTH = 480;

private int HEIGHT = 320;

private PerspectiveCamera camera; private Texture backgroundtexture; private SpriteBatch batch;

private Tombol

back,save,layarkendaraan,tbgm,teffect,ubgm,ueffect,vbgm,veffect; private int sensivity=0;

private int sensivitymax=3;

private boolean cback,csave,cbgm,ceffect,keyback,cplayeffect; private int timeplayeffect=0;

private int timeplayeffectmax=20; private float wbgm,weffect; private boolean hapusawal; private float volbgm,voleffect; Menu menu;

Start start;

public MenuOption(Start s,Menu m) { hapusawal=false; menu=m; start=s; backgroundtexture = new Texture(Gdx.files.internal("texture/backgroundmenu.jpg")); batch=new SpriteBatch(); csave=false; cback=false; cbgm=false; ceffect=false;

(8)

keyback=false; cplayeffect=false; Gdx.input.setCatchBackKey(true); volbgm=start.getvolumeaudio(0); voleffect=start.getvolumeaudio(1); }

public void dispose() { backgroundtexture.dispose(); batch.dispose(); back.dispose(); save.dispose(); layarkendaraan.dispose(); tbgm.dispose(); teffect.dispose(); ubgm.dispose(); ueffect.dispose(); vbgm.dispose(); veffect.dispose(); }

public void pause() { }

public void render(float arg0) { cektombol();

Gdx.gl.glEnable(GL10.GL_TEXTURE_2D);

Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );

camera.update();//tanpa update camera tidak jalan camera.apply(Gdx.gl10); batch.begin(); batch.draw(backgroundtexture, 0, 0,WIDTH,HEIGHT); batch.end(); layarkendaraan.gambar(); tbgm.gambar(); teffect.gambar(); ubgm.gambar();

(9)

ueffect.gambar(); vbgm.gambar(); veffect.gambar(); back.gambar(); save.gambar(); if(hapusawal==false) { if(menu!=null) { menu.dispose(); } hapusawal=true; } }

public void resize(int arg0, int arg1) {

camera = new PerspectiveCamera(67,arg0, arg1); WIDTH=arg0; HEIGHT=arg1; save=new Tombol(-140,250,140,50,"save2.png",arg0,arg1,10,10); save.setletaktekan(-140,250, 140, 50); save.setujunganimasi(50,-140,0,50); back=new Tombol(480,250,140,50,"back12.png",arg0,arg1,10,10); back.setletaktekan(480,250, 140, 50); back.setujunganimasi(290,480,340,290); tbgm=new Tombol(-150,40,150,40,"bgm2.png",arg0,arg1,10,10); tbgm.setujunganimasi(60,-150,0,60); teffect=new Tombol(-150,130,150,40,"effect2.png",arg0,arg1,10,10); teffect.setujunganimasi(60,-150,0,60); ubgm=new Tombol(500,90,400,20,"ukuran2.png",arg0,arg1,20,20); ubgm.setletaktekan(470,90, 440, 20); ubgm.setujunganimasi(60,500,480,50); ueffect=new Tombol(500,170,400,20,"ukuran2.png",arg0,arg1,20,20); ueffect.setletaktekan(480,170, 440, 20); ueffect.setujunganimasi(60,500,480,50);

(10)

vbgm=new Tombol(480,90,200,20,"volume2.png",arg0,arg1,20,20); vbgm.setujunganimasi(60,480,480,60); vbgm.setwidthvolume2(volbgm, 400); veffect=new Tombol(480,170,200,20,"volume2.png",arg0,arg1,20,20); veffect.setujunganimasi(60,480,480,60); veffect.setwidthvolume2(voleffect, 400); layarkendaraan=new Tombol(-460,10,460,200,"layarkendaraan2.png",arg0,arg1,20,20); layarkendaraan.setujunganimasi(10,-460,-460,10); }

public void resume() { } public void hide() {

// TODO Auto-generated method stub }

public void show() {

// TODO Auto-generated method stub }

}

Pada

Class MenuOption

ini pertama kali pada

constractor

akan ditetapkan

nilai-nilai awal yang akan ditampilkan dalam bentuk

bar

panjang

horizontal

yang

mewakili

volume

awal yang sebelumnya telah tercatat di

file

atau deklarasi baru

yang sebelumnya telah dilakukan oleh

Class Start

. Lalu gambar-gambar yang

dibutuhkan pertama kali akan diambil dan dideklarasikan oleh

object

dari

Class

Tombol

pada prosedur

resize(int arg0, int arg1)

, karena untuk menetapkan

jalannya untuk semua device maka akan diambil dulu panjang dan tinggi device

dari fungsi tersebut dengan hasil

arg0

adalah panjang dan

arg1

adalah lebar. Dan

pada fungsi

render()

ini terdapat suatu pengecekan untuk melakukan

dispose()

terhadap

screen

sebelumnya supaya tidak memperberat kerja

device

. Pengecekan

ini dilakukan di fungsi

render()

supaya ketika perpindahan screen gambar

(11)

background

dari

menu

tidak hilang. Prosedur ini memiliki struktur yang sama

dengan prosedur pada

Class Menu

Pesawat dan

Class Menu

yang lainnya yang

ada pada segmen

class

4.2., hanya saja sebagian

class

seperti

class Menu

Pesawat

memiliki sedikit tambahan yaitu variabel

sensitivity

yang berguna untuk

mengurangi

sensitivity

penekanan

user

terhadap tombol kiri dan kanan ketika

memilih kendaraan yang akan dipakai bertanding. Tetapi sebagian besar isi dari

class

ini dan

class

menu lainnya seperti

class Menu, MenuBuy, MenuLoad

, dan

MenuMap

hampir sama, hanya beda pada fungsi

dispose menu

sebelumnya dan

banyaknya tombol yang diperlukan.

Selain untuk

menu Implements Screen

juga digunakan untuk

screen

utama

jalannya pertandingan dalam

game

yaitu dalam

class MyGame

. Berikut

merupakan sebagian

sourcecode

dari

class MyGame

:

Segmen 4.2.7

Class MyGame

package com.libgdx; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import android.util.Log; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Screen; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g3d.loaders.obj.ObjLoader; import com.badlogic.gdx.utils.GdxRuntimeException;

public class MyGame implements Screen{ private float WIDTH=480;

(12)

private float HEIGHT=320; private Camera camera; public Pesawat[] p; private Texture mapt; private Mesh map;

private SpriteBatch batch; private Texture HPtexture; private Texture iconbonus; private Texture[] HPbar; private BitmapFont font;

private float widthmap,heightmap; private Texture galaxyt;

private Mesh galaxy;

private Pixmap cekmap,cekfinish;

private float[] pathx,pathz,pathy,startx,starty,startz; private int

jumlahpath,jumlahpesawat,i,j,k,indexpitawal,indexpitakhir,indexuser; private boolean hapusawal;

MenuMap menumap;

private int jumlahbonus; private ItemBonus[] bonus; private int[] statuspath; private int[] indexceklap; private int jumlahceklap; private boolean lastlap=false; Start start;

private Texture warning,rem,pitstop; private Texture[] panelmulai;

private int waktutunggu; boolean startgame;

private int indexpanel=0; private int ranking; private boolean tampillap; private int waktutampillap; private int waktutunggumax;

public MyGame(Start s,MenuMap mm) { jumlahbonus=20; bonus=new ItemBonus[20]; for(i=0;i<jumlahbonus;i++) {

(13)

bonus[i]=new ItemBonus(); } batch=new SpriteBatch(); HPbar=new Texture[2]; panelmulai=new Texture[3]; panelmulai[0] = new Texture(Gdx.files.internal("texture/stop.png")); panelmulai[1] = new Texture(Gdx.files.internal("texture/ready.png"));

panelmulai[2] = new Texture(Gdx.files.internal("texture/go.png")); iconbonus = new

Texture(Gdx.files.internal("texture/iconbonus2.png"));

warning = new Texture(Gdx.files.internal("texture/warning2.png")); pitstop = new Texture(Gdx.files.internal("texture/pitstop.png")); rem = new Texture(Gdx.files.internal("texture/rem.png"));

HPbar[0] = new Texture(Gdx.files.internal("texture/barhp.png")); HPbar[1] = new Texture(Gdx.files.internal("texture/barhp2.png")); hapusawal=false; menumap=mm; startgame=false; waktutunggu=0; start=s; tampillap=false; jumlahpesawat=5; waktutampillap=200; waktutunggumax=200;

galaxyt = new Texture(Gdx.files.internal("texture/galaxy.jpg")); galaxy = ObjLoader.loadObj(Gdx.files.internal("obj/galaxy.obj").read(),true); ranking=0; setpathmap(start.getindexmap()); setkendaraan(start.getindexlevel(),start.getindexkendaraan()); Gdx.input.setCatchBackKey(true); } }

(14)

Sourcecode

diatas merupakan

constractor

dari

class MyGame

yang

menjadi awal untuk mendeklarasikan dan memberi nilai awal dari variabel, serta

menentukan jumlah kendaraan dan

bonus.

4.3.

Implementasi Class Object Pendukung

Class-class ini berguna sebagai pembentuk object yang terdapat dalam

menu dan game yang dijalankan. Object dari kelas ini akan mewakili

masing-masing object yang akan ditampilkan pada background.

Berikut merupakan segmen

class

4.3.1. yaitu

class Tombol

:

Segmen 4.3.1.

Class Tombol

package com.libgdx; import android.util.Log; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class Tombol { private float x,y;

private float kecepatan,kecepatan2; private float width,height;

private Texture texture; private float xt,yt;

private float widtht,heightt; private float ujunganimasiawal; private float ujunganimasiakhir; private float ujunganimasitengah; private float ujunganimasitekan; private float wlayar,hlayar; private boolean

canimasiawal,canimasiakhir,cektekan,canimasitengah; private SpriteBatch batch;

(15)

private BitmapFont font; private String textfont; private boolean cekfont; float xfont,yfont;

public Tombol(float xx,float yy, float w,float h,String textur,float wl,float hl,float k,float k2)

{ cekfont =false; texture = new Texture(Gdx.files.internal("texture/"+textur)); wlayar=wl; hlayar=hl; width=w*wlayar/480; height=h*hlayar/320; x=xx*wlayar/480; y=hlayar-(yy*hlayar/320)-height; batch=new SpriteBatch(); canimasiakhir=false; canimasiawal=false; canimasitengah=false; cektekan=false; kecepatan=k*wlayar/480; kecepatan2=k2*hlayar/320; font = new BitmapFont(Gdx.files.internal("font/digifacewide.fnt"), Gdx.files.internal("font/digifacewide.png"), false); font.setScale(wlayar/480); textfont=""; } }

Class

ini merupakan

class

yang sebagian besar dipakai oleh

class-class

menu

pada segmen

class

4.2.

class

ini memiliki fungsi-fungsi seperti mengatur

peletakan tombol pada layar, mengecek penekanan tombol, memberikan

text

pada

tombol, menampilkan tombol dengan gambar dari

file

, serta mengatur jalan

animasi

dari tombol saat awal dan perpindahan screen. Selain class tombol juga

terdapat class ItemBonus yang mengatur semua item bonus.

(16)

Berikut merupakan

source code

dari segmen

class

4.3.2 yaitu

class

ItemBonus

:

Segmen 4.3.2.

Class ItemBonus

package com.libgdx; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g3d.loaders.obj.ObjLoader; public class ItemBonus {

//status 0=set //status 1=siap; private float x,y,z; private float width; private int jenis;

private int status,indexpathAI,indextempat; private Mesh[] model;

private Texture[] texture; private float[] head; private float rotatefh; private float kecepatan; private int indexpemegang; private Mesh tanda;

private Texture ttanda;

public ItemBonus() { width=1; x=0; y=0; z=0; jenis=0; status=0;

(17)

indextempat=0; head=new float[2]; texture=new Texture[6]; texture[0] = new Texture(Gdx.files.internal("bonus/ranjau.jpg")); texture[1] = new Texture(Gdx.files.internal("bonus/kecepatan.jpg")); texture[2] = new Texture(Gdx.files.internal("bonus/pelindung.jpg")); texture[3] = new Texture(Gdx.files.internal("bonus/misil0.jpg")); texture[4] = new Texture(Gdx.files.internal("bonus/misil1.jpg")); texture[5] = new Texture(Gdx.files.internal("bonus/misil2.jpg")); model=new Mesh[4]; model[0] = ObjLoader.loadObj(Gdx.files.internal("bonus/ranjau.obj").read(),true); model[1] = ObjLoader.loadObj(Gdx.files.internal("bonus/kecepatan.obj").read(),true); model[2] = ObjLoader.loadObj(Gdx.files.internal("bonus/pelindung.obj").read(),true); model[3] = ObjLoader.loadObj(Gdx.files.internal("bonus/misil.obj").read(),true); rotatefh=0; kecepatan=4; indexpemegang=-1; tanda = ObjLoader.loadObj(Gdx.files.internal("bonus/tanda.obj").read(),true); ttanda = new Texture(Gdx.files.internal("bonus/tanda.jpg"));

} }

Class ItemBonus ini merupakan class yang mengatur Mesh item bonus

yang bersebaran di lintasan. Class ini berhubungan dengan fungsi dari class

Pesawat yang juga melakukan pengecekan terhadap item bonus. Dalam class ini

terdapat beberapa fungsi penting yaitu:

(18)

Berikut merupakan

source code

dari segmen

class

4.3.3 yaitu

class

Pesawat:

Segmen 4.3.3.

Class

Pesawat

package com.libgdx; import android.util.Log; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.g3d.loaders.obj.ObjLoader;

public class Pesawat {

private Mesh model,cek; private Texture texture; private float x,y,z;

private float rotatef,rotatefh; private float[] bataskiri; private float[] bataskanan; private float[] batasdepan; private float kecepatan; private float kecepatanmax; private float kecepatanmin;

private float selisihkecepatan,boost; private float xcam,ycam,zcam;

private int indexpathAI; private float[] sayapkiri; private float[] sayapkanan; private float[] headtembak; private float[] ekortembak;

private float[] depankiri,depankanan,belakangkiri,belakangkanan; private float acceleration;

(19)

private float HPmax; private float rotatev; private float rotatefh2;

private float accelerationbonus;

private boolean pegangbonus,effectbonus; private int jenisbonus,jeniseffect,indexbonus; private float HPterakhir;

private int timeeffect;

private boolean cekjalanAI1,masukpit,cekgarisfinish; private int lap;

private int ceklapnow; private boolean selesai;

public Pesawat(String pesawat,String textur,float xx,float yy,float zz) { headtembak=new float[2]; ekortembak=new float[2]; texture = new Texture(Gdx.files.internal("kendaraan/"+textur)); model = ObjLoader.loadObj(Gdx.files.internal("kendaraan/"+pesawat).read(),true); x=xx; y=yy; z=zz; rotatef=0; rotatefh=0; rotatev=0; rotatefh2=0; headtembak[0]=x; headtembak[1]=z-30; ekortembak[0]=x; ekortembak[1]=z+10; pegangbonus=false; jenisbonus=-1; effectbonus=false; timeeffect=0; boost=0; accelerationbonus=1;

(20)

masukpit=false; lap=0; ceklapnow=0; cekgarisfinish=false; xcam=xx; ycam=yy+2; zcam=zz+9; indexpathAI=0; cekjalanAI1=true; selesai=false; } }

Class

Pesawat ini merupakan

class

yang mengatur

Mesh

dari kendaraan,

AI(Artificial Intellligent)

, pengecekan tabrak, serta penyetiran

user

terhadap

kendaraan yang nantinya akan ditampilkan di

class MyGame

dengan fungsi

gambar().

Class

ini memiliki fungsi untuk menetapkan

path

baik

user

maupun

AI

ketika mengitari lintasan. Berikut merupakan beberapa fungsi dan prosedur yang

penting dalam

class Pesawat

:

Segmen 4.3.3.1. cekluncur

bonus

AI

public boolean cekluncurbonusAI(int levelgame,float[] dkanan,float[] dkiri,float[] bkanan,float[] bkiri)

{ if(pegangbonus==true) { waktupegangbonus++; if(waktupegangbonus>2000) { levelgame=1; waktupegangbonus=0; } if(levelgame==1) { pegangbonus=false; effectbonus=false; if(jenisbonus==1) { timeeffect=0;

(21)

effectbonus=true; jeniseffect=1; boost=2; } else if(jenisbonus==2) { timeeffect=0; effectbonus=true; jeniseffect=2; HPterakhir=HP; } return true; } else if(levelgame==2) { if(jenisbonus==0) { if(cektabrakpesawatdepan(dkanan, dkiri, bkanan, bkiri, ekortembak[0], ekortembak[1])==false)

{ pegangbonus=false; effectbonus=false; return true; } } else if(jenisbonus==1) { pegangbonus=false; timeeffect=0; effectbonus=true; jeniseffect=1; boost=2; return true; } else if(jenisbonus==2) { pegangbonus=false; timeeffect=0; effectbonus=true; jeniseffect=2; HPterakhir=HP; return true; }

(22)

else if(jenisbonus==3 || jenisbonus==4 || jenisbonus==5)

{

if(cektabrakpesawatdepan(dkanan, dkiri, bkanan, bkiri, batasdepan[0], batasdepan[1])==false)

{ pegangbonus=false; effectbonus=false; return true; } else {

float[] headtembak=new float[2]; boolean cek=true; int i=0; float r=(-90-rotatefh); do { headtembak[0]=(float) (batasdepan[0]+Math.cos(Math.toRadians(r))*i); headtembak[1]=(float) (batasdepan[1]+Math.sin(Math.toRadians(r))*i); if(cektabrakpesawatdepan(dkanan, dkiri, bkanan, bkiri, headtembak[0], headtembak[1])==false)

{

cek=false; }

i+=2;

}while(i<=(jarakhead/2) && cek==true); if(cek==false) { pegangbonus=false; effectbonus=false; return true; } } } } else if(levelgame==3) { if(jenisbonus==0) { if(cektabrakpesawatdepan(dkanan, dkiri, bkanan, bkiri, ekortembak[0], ekortembak[1])==false)

(23)

{ pegangbonus=false; effectbonus=false; return true; } } else if(jenisbonus==1) { pegangbonus=false; timeeffect=0; effectbonus=true; jeniseffect=1; boost=2; return true; } else if(jenisbonus==2) { pegangbonus=false; timeeffect=0; effectbonus=true; jeniseffect=2; HPterakhir=HP; return true; }

else if(jenisbonus==3 || jenisbonus==4 || jenisbonus==5)

{

if(cektabrakpesawatdepan(dkanan, dkiri, bkanan, bkiri, batasdepan[0], batasdepan[1])==false)

{ pegangbonus=false; effectbonus=false; return true; } else {

float[] headtembak=new float[2]; boolean cek=true; int i=0; float r=(-90-rotatefh); do { headtembak[0]=(float) (batasdepan[0]+Math.cos(Math.toRadians(r))*i);

(24)

headtembak[1]=(float) (batasdepan[1]+Math.sin(Math.toRadians(r))*i);

if(cektabrakpesawatdepan(dkanan, dkiri, bkanan, bkiri, headtembak[0], headtembak[1])==false)

{

cek=false; }

i+=2;

}while(i<=jarakhead && cek==true); if(cek==false) { pegangbonus=false; effectbonus=false; return true; } } } } } return false; }

Fungsi di atas adalah untuk mengatur apa yang dilakukan AI berdasarkan

level

apabila AI mendapatkan

item bonus

. Apabila

level

yang dipilih

user

adalah

level

1 atau

easy

maka AI akan melepaskan atau meluncurkan segala jenis

item

bonus

yang dibawa. Sedangkan apabila

user

memilih

level 2

atau

medium

maka

apabila di belakang AI terdapat kendaraan lain dan AI sedang memegang ranjau

maka AI akan segera menjatuhkan ranjau tersebut dan apabila di depan AI

terdapat kendaraan lain dan berada dalam setengah jarak tembak maka AI akan

menembakkan tembakan

item

serangan. Untuk

level 3

atau

expert

sama seperti

medium,

hanya saja jarak tembak tidak dikurangi. Dan apabila AI telah memegang

item

lebih dari waktu pegang, maka AI akan meluncurkan

item

tersebut. Selain itu

item

yang dapat menambah kecepatan dan pelindung akan segera dipakai apabila

didapatkan.

Segmen 4.3.3.2. naikturun

public void naikturun(float[] ptx,float[] pty,float[] ptz) {

(25)

tinggi=Math.abs(pty[indexpathAI]-y); float jarakpath; jarakpath=(float) Math.sqrt(Math.pow(ptx[indexpathAI]-x, 2)+Math.pow(ptz[indexpathAI]-z, 2)); double sudut; sudut=Math.atan(tinggi/jarakpath); float jaraktinggi = 0; if(pty[indexpathAI]>y) { if(Math.toDegrees(sudut)>rotatev) { if(rotatev+1<=Math.toDegrees(sudut)) { rotatev=rotatev+1f; } else { rotatev=(float) Math.toDegrees(sudut); } } jaraktinggi=(float) (Math.sin(sudut)*kecepatan); } else if(pty[indexpathAI]<y) { if(Math.toDegrees(sudut)*-1<rotatev) { if(rotatev-1>=Math.toDegrees(sudut)*-1) { rotatev=rotatev-1f; } else { rotatev=(float) Math.toDegrees(sudut)*-1; } } jaraktinggi=(float) (Math.sin(sudut)*kecepatan*-1); }

if(Math.toDegrees(sudut)<=1 && Math.toDegrees(sudut)>=0) {

if(0>rotatev) {

(26)

if(rotatev+2<=0) { rotatev=rotatev+2f; } else { rotatev=0; } } if(0<rotatev) { if(rotatev-2>=0) { rotatev=rotatev-2f; } else { rotatev=0; } } } y=y+jaraktinggi; ycam=ycam+jaraktinggi; }

Fungsi di atas digunakan untuk mengatur kendaraan untuk dapat menaiki

dan menuruni bukit dari lintasan yang ada berdasarkan path yang ada. Seperti

yang telah dijelaskan pada bab 3 dalam

source code

ini dicari ketinggian

kendaraan berdasarkan kecepatan kendaraan, selain itu juga arah

mesh

ke atas dan

ke bawah dengan variabel rotatev sesuai dengan besar sudut antara kendaraan

dengan tinggi

path.

Segmen 4.3.3.3. cektabrakpesawatdepan

public boolean cektabrakpesawatdepan(float[] dkanan,float[] dkiri,float[] bkanan,float[] bkiri,float bx,float bz)

{

float jarakbatas1,jarakbatas2; double sudut;

float t1,t2; boolean c1,c2;

(27)

float lebar=(float) Math.sqrt(Math.pow(dkiri[0]-bkiri[0],2)+Math.pow(dkiri[1]-bkiri[1], 2));

float panjang=(float) Math.sqrt(Math.pow(dkiri[0]-dkanan[0],2)+Math.pow(dkiri[1]-dkanan[1], 2)); jarakbatas1=(float) Math.sqrt(Math.pow((dkiri[0]-bx), 2)+Math.pow((dkiri[1]-bz), 2)); jarakbatas2=(float) Math.sqrt(Math.pow((bkiri[0]-bx), 2)+Math.pow((bkiri[1]-bz), 2)); sudut=Math.acos((Math.pow(lebar, 2)+Math.pow(jarakbatas2, 2)-Math.pow(jarakbatas1, 2))/(2*lebar*jarakbatas2)); t1=(float) (jarakbatas2*Math.sin(sudut)); jarakbatas1=(float) Math.sqrt(Math.pow((bkanan[0]-bx), 2)+Math.pow((bkanan[1]-bz), 2)); jarakbatas2=(float) Math.sqrt(Math.pow((dkanan[0]-bx), 2)+Math.pow((dkanan[1]-bz), 2)); sudut=Math.acos((Math.pow(lebar, 2)+Math.pow(jarakbatas2, 2)-Math.pow(jarakbatas1, 2))/(2*lebar*jarakbatas2)); t2=(float) (jarakbatas2*Math.sin(sudut)); if(Math.floor(t1+t2)==Math.floor(panjang)) { c1=false; } else { c1=true; } jarakbatas1=(float) Math.sqrt(Math.pow((dkanan[0]-bx), 2)+Math.pow((dkanan[1]-bz), 2)); jarakbatas2=(float) Math.sqrt(Math.pow((dkiri[0]-bx), 2)+Math.pow((dkiri[1]-bz), 2)); sudut=Math.acos((Math.pow(panjang, 2)+Math.pow(jarakbatas2, 2)-Math.pow(jarakbatas1, 2))/(2*panjang*jarakbatas2)); t1=(float) (jarakbatas2*Math.sin(sudut)); jarakbatas1=(float) Math.sqrt(Math.pow((bkiri[0]-bx), 2)+Math.pow((bkiri[1]-bz), 2)); jarakbatas2=(float) Math.sqrt(Math.pow((bkanan[0]-bx), 2)+Math.pow((bkanan[1]-bz), 2)); sudut=Math.acos((Math.pow(panjang, 2)+Math.pow(jarakbatas2, 2)-Math.pow(jarakbatas1, 2))/(2*panjang*jarakbatas2)); t2=(float) (jarakbatas2*Math.sin(sudut)); if(Math.floor(t1+t2)==Math.floor(lebar)) {

(28)

c2=false; } else { c2=true; }

if(c1==false && c2==false) {

return false; }

return true; }

Fungsi di atas digunakan untuk melakukan pengecekan apakah suatu

kendaraan telah menabrak kendaraan lain dengan menggunakan rumus persamaan

segitiga yang ada pada bab 3.

Segmen 4.3.3.4. jalanAI

public boolean jalanAI(Pixmap px,float w,float h,float[] dkanan,float[] dkiri,float[] bkanan,float[] bkiri)

{

boolean cek1=true; boolean cek2=true; boolean cek3=true;

if(cektabrak(px, batasdepan[0], batasdepan[1], w, h)==false) {

kecepatan=0;

if(cektabrak(px, bataskiri[0], bataskiri[1],w,h)==false) {

setirAI(acceleration); }

else if(cektabrak(px, bataskanan[0], bataskanan[1],w,h)==false) { setirAI(acceleration*-1); } cek1=false; }

(29)

{

kecepatan=kecepatanmin; setirAI(acceleration); cek1=false;

}

else if(cektabrak(px, bataskanan[0], bataskanan[1],w,h)==false) {

kecepatan=kecepatanmin; setirAI(acceleration*-1); cek1=false;

}

if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri, batasdepan[0], batasdepan[1])==false) { kecepatan=kecepatanmin; if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri,bataskiri[0], bataskiri[1])==true) { setirAI(acceleration*-1); }

else if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri,bataskanan[0], bataskanan[1])==true) { setirAI(acceleration); } cek2=false; }

else if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri,bataskiri[0], bataskiri[1])==false) { kecepatan=kecepatanmin; setirAI(acceleration); cek2=false; }

else if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri,bataskanan[0], bataskanan[1])==false) { kecepatan=kecepatanmin; setirAI(acceleration*-1); cek2=false; }

if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri,sayapkiri[0], sayapkiri[1])==false || cektabrak(px,sayapkiri[0], sayapkiri[1], w, h)==false)

(30)

{

setirAI(acceleration); cek3=false;

}

else if(cektabrakpesawatdepan(dkanan, dkiri,

bkanan,bkiri,sayapkanan[0], sayapkanan[1])==false || cektabrak(px, sayapkanan[0], sayapkanan[1], w, h)==false)

{ setirAI(acceleration*-1); cek3=false; } if(cektabrakpesawatdepan(dkanan, dkiri, bkanan,bkiri,belakangkiri[0], belakangkiri[1])==false || cektabrak(px,belakangkiri[0], belakangkiri[1], w, h)==false)

{

setirAI(acceleration); return true;

}

else if(cektabrakpesawatdepan(dkanan, dkiri,

bkanan,bkiri,belakangkanan[0], belakangkanan[1])==false || cektabrak(px,belakangkanan[0], belakangkanan[1], w, h)==false)

{ setirAI(acceleration*-1); return true; } if(cek1==false ||cek2==false||cek3==false) { return false; } return true; }

Fungsi di atas merupakan prioritas paling utama dalam melakukan

pengecekan AI, karena fungsi di atas akan melakukan pengecekan terhadap

penabrakan dinding dan kendaraan lain dan melakukan tindak lanjut terhadap apa

yang terjadi dengan melakukan pembelokan sesuai dengan bagian yang ditabrak.

Segmen 4.3.3.5. jalanAI2

public boolean jalanAI2(float xbonus,float zbonus,int statusbonus) {

(31)

float test;

test = (batasdepan[0]-x)*(xbonus-x) + (batasdepan[1]-z)*(zbonus-z);

float[] jarakbonus=new float[3];

jarakbonus[0]=(float) Math.sqrt(Math.pow(batasdepan[0]-xbonus, 2)+Math.pow(batasdepan[1]-zbonus, 2));

if(test>0 && jarakbonus[0]<=40 && statusbonus==1 && pegangbonus==false && effectbonus==false)

{

menujupath(xbonus, zbonus); return true;

}

else if(test>0 && jarakbonus[0]<=20 && statusbonus==3 ) { if(level==2 || level==3) { float xc,zc,xc2,zc2; xc=rotatex(batasdepan[0]-x,batasdepan[1]-z,acceleration)+x; zc=rotatez(batasdepan[0]-x,batasdepan[1]-z,acceleration)+z; jarakbonus[1]=(float) Math.sqrt(Math.pow(xc-xbonus, 2)+Math.pow(zc-zbonus, 2)); xc2=rotatex(batasdepan[0]-x,batasdepan[1]-z,acceleration*-1)+x; zc2=rotatez(batasdepan[0]-x,batasdepan[1]-z,acceleration*-1)+z; jarakbonus[2]=(float) Math.sqrt(Math.pow(xc2-xbonus, 2)+Math.pow(zc2-zbonus, 2)); if(jarakbonus[1]>=jarakbonus[2]) { setirAI(acceleration); } else { setirAI(acceleration*-1); } return true; } } return false; }

(32)

Fungsi di atas merupakan prioritas ke dua dalam melakukan pengecekan

AI, karena fungsi di atas akan melakukan pengecekan terhadap penghindaran

jebakan dan serangan serta pengambilan

item bonus

yang terlihat. Dan apabila

level easy

yang

user

pilih maka AI tidak dapat melakukan penghindaran terhadap

ranjau.

Segmen 4.3.3.6. jalanAI3

public void jalanAI3(float[] ptx,float[] ptz) {

menujupath(ptx[indexpathAI], ptz[indexpathAI]); }

Fungsi di atas merupakan prioritas terakhir dalam melakukan pengecekan

AI, karena fungsi di atas hanya akan membuat AI berjalan sesuai

path

yang telah

ditentukan sesuai dengan rumus

steering

yang ada pada bab 3.

Segmen 4.3.3.7. setjalan

path

AI

public void setjalanpathAI(float[] ptx,float[] ptz,int indexpitstart,int indexpitfinish)

{

float[] jarakpath=new float[9]; int[] indexpath=new int[9]; int[] operator=new int[9]; operator[0]=0; operator[1]=1; operator[2]=2; operator[3]=3; operator[4]=4; operator[5]=-1; operator[6]=-2; operator[7]=-3; operator[8]=-4; for(int i=0;i<9;i++) { indexpath[i]=indexpathAI+operator[i]; if(HP>0.1*HPmax) {

(33)

if(indexpath[i]>=indexpitstart) { if(operator[i]<0) { indexpath[i]=0; } else { indexpath[i]=operator[i]; } } } if(indexpath[i]>=indexpitfinish+1) { if(operator[i]<0) { indexpath[i]=0; } else { indexpath[i]=operator[i]; } } if(indexpath[i]<0) { indexpath[i]=0; } jarakpath[i]=(float) Math.sqrt(Math.pow(ptx[indexpath[i]]-x, 2)+Math.pow(ptz[indexpath[i]]-z, 2)); } int index=indexpath[0]; float min=jarakpath[0]; for(int i=0;i<9;i++) { if(jarakpath[i]<min) { min=jarakpath[i]; index=indexpath[i]; } }

float[] jarakpath2=new float[2]; int[] indexpath2=new int[2]; int[] operator2=new int[2]; operator2[0]=0;

(34)

operator2[1]=1; //operator2[2]=-1; for(int i=0;i<2;i++) { indexpath2[i]=index+operator2[i]; if(HP>0.1*HPmax) { if(indexpath2[i]>=indexpitstart) { if(operator2[i]<0) { indexpath2[i]=0; } else { indexpath2[i]=operator2[i]; } } } if(indexpath2[i]>=indexpitfinish+1) { if(operator2[i]<0) { indexpath2[i]=0; } else { indexpath2[i]=operator2[i]; } } if(indexpath2[i]<0) { indexpath2[i]=0; } jarakpath2[i]=(float) Math.sqrt(Math.pow(ptx[indexpath2[i]]-x, 2)+Math.pow(ptz[indexpath2[i]]-z, 2)); } ///// if(jarakpath2[0]<=30) { if(indexpath2[1]>=indexpathAI) { indexpathAI=indexpath2[1];

(35)

} else { if(HP>0.1*HPmax) { if(indexpathAI==indexpitstart-1) { indexpathAI=indexpath2[1]; } } else { if(indexpathAI==indexpitfinish) { indexpathAI=indexpath2[1]; } } } } else { if(indexpath2[0]>=indexpathAI) { indexpathAI=indexpath2[0]; } else { if(HP>0.1*HPmax) { if(indexpathAI==indexpitstart-1) { indexpathAI=indexpath2[0]; } } else { if(indexpathAI==indexpitfinish) { indexpathAI=indexpath2[0]; } } } }

(36)

float jarakpathbaru=(float) Math.sqrt(Math.pow(ptx[indexpathAI]-x, 2)+Math.pow(ptz[indexpathAI]-z, 2)); if(jarakpathbaru<7) { indexpathAI++; if(HP>0.1*HPmax) { if(indexpathAI>=indexpitstart) { indexpathAI=0; } } if(indexpathAI==indexpitfinish+1) { indexpathAI=0; } } if(indexpathAI>=indexpitstart+1) { kecepatan=kecepatanmin+0.3f; //HP=HPmax; } if(indexpathAI>=indexpitfinish) { HP=HPmax; } }

Fungsi di atas digunakan oleh AI untuk menentukan

path

yang akan dituju

serta mencari

path

apabila AI keluar dari jalur

path

dengan mencari

path

dari

path

AI terakhir ditambah dan dikurangi empat dan mengambil

path

terdekat serta

mengatur apakah AI harus masuk

pitstop

atau tidak. Pada

source code

di atas

dijelaskan pertama kali AI akan mencari

path

terdekat dari AI dari range empat

path

dari

path AI

terakhir, kemudian mencari range 3 dari

path

terdekat dan

apabila jarak AI sekarang lebih kecil dari 30 maka AI akan mencari

path

berikutnya.

(37)

Segmen 4.3.3.8. cari

pathuser

public void caripathuser(float[] ptx,float[] ptz,int indexpitstart,int indexpitakhir)

{

if(masukpit==false) {

float[] jarakpath=new float[9]; int[] indexpath=new int[9]; int[] operator=new int[9]; operator[0]=0; operator[1]=1; operator[2]=2; operator[3]=3; operator[4]=4; operator[5]=-1; operator[6]=-2; operator[7]=-3; operator[8]=-4; for(int i=0;i<9;i++) { indexpath[i]=indexpathAI+operator[i]; if(indexpath[i]>=indexpitakhir+1) { indexpath[i]=operator[i]; } if(indexpath[i]<0) { indexpath[i]=indexpitakhir; } jarakpath[i]=(float) Math.sqrt(Math.pow(ptx[indexpath[i]]-x, 2)+Math.pow(ptz[indexpath[i]]-z, 2)); } int index=indexpath[0]; float min=jarakpath[0]; for(int i=0;i<9;i++) { if(jarakpath[i]<min) { min=jarakpath[i]; index=indexpath[i]; }

(38)

}

float[] jarakpath2=new float[3]; int[] indexpath2=new int[3]; int[] operator2=new int[3]; operator2[0]=0; operator2[1]=1; operator2[2]=-1; for(int i=0;i<3;i++) { indexpath2[i]=index+operator2[i]; if(indexpath2[i]>=indexpitakhir+1) { indexpath2[i]=operator2[i]; } if(indexpath2[i]<0) { indexpath2[i]=indexpitakhir; } jarakpath2[i]=(float) Math.sqrt(Math.pow(ptx[indexpath2[i]]-x, 2)+Math.pow(ptz[indexpath2[i]]-z, 2)); } if(jarakpath2[0]<=10) { float test; int i=0; boolean cek=true; do { test = (batasdepan[0]-x)*(ptx[indexpath2[i]]-x) + (batasdepan[1]-z)*(ptz[indexpath2[i]]-z); if(test>0) { index=indexpath2[i]; cek=false; } i++;

}while(i<3 && cek==true); indexpathAI=index;

} else {

(39)

} }

float jarakpathpit=(float)

Math.sqrt(Math.pow(ptx[indexpitstart]-x, 2)+Math.pow(ptz[indexpitstart]-z, 2));

if(jarakpathpit<=20 && masukpit==false) { masukpit=true; indexpathAI=indexpitstart; acceleration+=3; } if(masukpit==true) { kecepatan=kecepatanmin+0.3f; jarakpathpit=(float) Math.sqrt(Math.pow(ptx[indexpathAI]-x, 2)+Math.pow(ptz[indexpathAI]-z, 2)); if(jarakpathpit<8) { indexpathAI++; if(indexpathAI>=indexpitakhir+1) { HP=HPmax; indexpathAI=0; masukpit=false; acceleration-=3; } } } }

Fungsi di atas hampir sama dengan fungsi setjalan

path

AI, hanya saja fungsi

di atas hanya digunakan untuk user supaya dapan menaiki dan menuruni

perbukitan serta mengatur supaya ketika memasuki pitstop kendaraan user dapat

dengan otomatis berjalan.

Gambar

Tabel 4.1. Daftar class
Tabel 4.2. Daftar prosedur dan fungsi

Referensi

Dokumen terkait

(1) Untuk memperoleh izin sebagaimana dimaksud dalam pasal 26, Kepala Dinas Kesehatan Kabupaten/Kota mengajukan permohonan tertulis kepada Bupati/Walikota melalui

- merujuk kepada syarikat yang mengeluarkan produk yang sama dan dijual dalam pasaran yang sama dengan produk usahawan4. - pesaing boleh memberi sumbangan dari segi meningkatkan

Penelitian ini bertujuan untuk menentukan survival rate serta memperkirakan Total Akumulasi Biomassa Atas Permukaan dari jenis-jenis pohon utama hutan rawa gambut yang digunakan

Berdasarkan hasil analisis data dan pemba- hasan yang telah diurai, maka dapat diambil kesimpulan bahwa variabel PDRB di kota DIY pada tahun 2006-2012 dipengaruhi oleh Pena-

Berdasarkan hasil penelitian yang didapatkan bahwa ekstrak etanol daun Sirih ( Piper betle L) berpengaruh terhadap proses spermatogenesis pada tikus putih jantan

Lalu masuk kedalam Reverse Osmosis Unit 1 dan 2, yang bekerja untuk memproduksi air bersih dan hasilnya masuk ke Reverse Osmosis Tank untuk pembuangannya (reject)

Menimbang, bahwa putusan Pengadilan Negeri Subang Nomor : 11/Pdt.Plw/2017/PN.Sng diucapkan pada tanggal 8 Agustus 2017 dengan di hadiri oleh Kuasa Hukum Terlawan

Epitel simpleks (Epitel pipih selapis). Ciri-cirinya, sitoplasma jernih, inti sel bulat terletak di tengah. Epitel ini terletak di pleura, alveolus paru-paru, kapsul bowman