Ganti Mobil: Picanto ke Brio

22 July 2016 at 22:03 | Posted in Uncategorized | 3 Comments

update 26 Juli: pengalaman menggunakan new brio sayta E cvt


Wah, terakhir posting seperti ini tahun 2007, alias 9 tahun yang lalu!

Berbeda dengan kasus terakhir saat saya pindah dari Katana ke Picanto, Picanto sebenarnya masih enak digunakan. Cuma lalulintas Bandung yang semakin macet, ditambah saya kena serangan asam urat di kaki kiri membuat mobil matic sepertinya menjadi keharusan.  AC mobil picanto juga kena service besar sehingga evaporator dan kondensor harus diganti. Artinya tidak lama lagi mungkin komponen besar yang lain akan mulai harus diganti. Mengingat mencari sparepart KIA lumayan susah, dan satu demi satu dealer KIA tutup,  maka terpaksa harus diganti nih secepatnya.

Fitur transmisi automatic menjadi prioritas utama. Seperti biasa, saya kemudian cari yang paling murah 🙂   Tentu Agya dan Ayla  jadi pertimbangan pertama. Tapi mesin yang hanya 1000cc dan banyak keluhan tentang getaran membuat saya mundur. Apalagi 1000cc matic juga akan lebih parah dibandingkan manual. Saya ingin mobil berikutnya punya tenaga dan akselerasi lebih besar daripada Picanto.

Oleh karena itu hanya ada satu alternatif, yaitu Brio E CVT.  Brio E CVT harganya 151jt; tenaga dan torsi: 90ps/6000rpm  dan 110Nm/4800. Dari sisi keamanan ada dual SRS Airbags dan  pretensioner+force limiter seatbelt. Sedangkan untuk rem ada ABS + EBD. Ini fitur yang paling penting bagi saya dan sebelumnya tidak ada atau kurang di Picanto lama yang saya miliki. Dari sisi bentuk, Brio bagus untuk bagian depan dan bagian samping. Sedangkan kalau belakang ya memang jelek sih.

Altenatif matic lain seperti Mirage, Sirion,  Picanto  harga matic-nya  berbeda cukup jauh diatas Brio tapi fiturnya malah lebih sedikit (setidaknya fitur yang saya anggap penting). Sedangkan Etios Valco tidak menyediakan versi matic.

Kalau dibandingkan, Mistsubisi Mirage matic versi termurah (178jt), sama-sama CVT, bedanya Mirage 3 silinder dengan tenaga & torsi: 77/6000 & 100/4000; tidak ada ABS+ABD. Sedangkan Sirion harganya 170jt; AT 4 kecepatan; 1300 cc; tanaga & torsi: 90/6000 & 116/4400 dengan pretensioner+force limiter seatbelt tapi tidak ada ABS+EBD.  Terakhir Picanto (171jt), AT 4 kecepatan; tenaga & torsi: 87/6000 &  119 Nm/4000 tanpa airbag, tanpa ABS. Untuk picanto kalau mau dapat ABS dan airbag, perlu ambil tipe Platinum seharga 185jt.  Jadi bagi saya jelas pilihannya berat untuk Brio, terutama karena harga dan faktor fitur ABS+EBD. Beberapa review juga menulis kelebihan adalah Brio lebih “fun to drive” dan lebih irit. Tentu tiap orang punya selera dan prioritas yang berbeda-beda, misalnya ada yang suka ruang yang lebih lapang, kenyamanan kursi, interior, bentuk dsb.

Update: Katanya discount bisa sangat besar untuk Mirage dan Sirion, jadi sebaiknya tanya dulu ke pihak sales.

Setelah saya testdrive (versi RS-CVT) semua sesuai ekspektasi. Selain rem yang lebih akurat dan akselerasi yang lebih mantap, pandangan juga lebih lega dibandingkan Picanto dan suspensi terasa lebih empuk (atau karena Picanto saya sudah tua umurnya?). Tapi memang kalau saya bandingkan dengan Sirion masih lebih empuk Brio untuk suspensinya.

Kelemahan mungkin dari stir yang terasa aneh karena biasa menggunakan hidrolik di Picanto, tapi memang sangat ringan.  Untuk yang lain bagi saya tidak terlalu penting dan sudah sesuailah dengan harganya.

Tentu saja versi RS tidak saya lirik, jauh lebih mahal dengan hanya perbedaan sedikit di interior dan eksterior saja.

Posting ini akan diupdate dengan review Brio  (semoga kalau jadi ).

Update: jadi beli, dan ini reviewnya: pengalaman menggunakan new brio sayta E cvt

Pelajaran dari PPDB Bandung tahun ini (2016)

1 July 2016 at 14:20 | Posted in Uncategorized | 1 Comment

Positif: Lebih baik daripada tahun lalu. Sosialisasi lebih bagus, aturan sudah disampaikan cukup lama. Kebijakan memisahkan kuota dalam wilayah vs luar wilayah bagus untuk mengurangi beban lalulintas kota bandung dan pemerataan kualitas intake. Jalur RMP (SKTM) sudah tidak ada gejolak lagi.

Negatif:

  • Jumlah kuota dalam/luar wilayah perlu dievaluasi, ada kuota luar wilayah yang super kecil (belasan kursi saja), ada kuota dalam wilayah yang kebanyakan sampai kosong. Bagaimana cara menghitung kuota ini? perlu lebih transparan.
  • Kosongnya kuota DW di sekolah favorit menurut dugaan saya karena kebijakan umur KK minimal 1 tahun. Artinya faktor kecurangan memanipulasi KK masih  menjadi tantangan di masa depan.
  • Data sebaran UN yang dapat digunakan untuk memprediksi PG, terlambat keluar, dan saat keluar sempat salah pula. Data kuota juga sempat salah.
  • Faktor data yang terlambat dan tidak akurat, ditambah aturan yang sering berganti, membuat prediksi PG menjadi sangat sulit, padahal hanya boleh pilih sekali. Efeknya banyak yang menunda pendaftaran sampai hari terakhir. Tahun depan PPDB SMA katanya akan dipegang propinsi sehingga aturan akan berubah lagi 😦
  • Sisa kuota yang tidak terpakai (jalur RMP, luar kota) seharusnya lebih cepat diputuskan untuk dialihkan kemana.
  • Support bisa dikatakan nol, Twitter/FB sangat jarang ditanggapi. Untung banyak ortu yg saling bantu dan gotong royong terutama via web https://bicarapassinggrade.wordpress.com
  • Situs PPDB sempat mengeluarkan data yang salah (tidak punya maintenance mode?) dan down dihari terakhir.
  • Penentuan jalur dalam wilayah, luar wilayah dan luar kota sepertinya manual, bukan otomatis oleh sistem. Ada beberapa kasus jalur tidak cocok dengan data. Bisa salah entry, bisa saja ada manipulasi karena jalur dalam wilayah lumayan menggiurkan.
  • Beberapa jam setelah peneutupan, kuota GW berubah karena mendapat limpahan dari DW, dan mengakibatkan perubahan besar. Itupun sepertinya masih belum berakhir karena sesuai perwal, PG luar kota tidak boleh lebih rendah dari PG GW. Hal-hal seperti ini membuat ketidakpastian semakin tinggi.

Saya pribadi bersyukur PPDB tahun ini adalah yang  terakhir bagi kami. Tinggal persiapan masuk kuliah 3 tahun lagi.

Petunjuk Singkat Praktek Lapangan / Kerja Praktek

18 January 2016 at 05:05 | Posted in Uncategorized | Leave a comment

Berdasarkan pengalaman saya di Ilkom menjadi pembimbing dan penguji mahasiswa Ilkom yang PLA, ada beberapa hal yang penting diperhatikan mahasiswa saat melaksanakan PLA.

Tujuan PLA adalah agar mahasiswa mendapat gambaran dan pengalaman singkat bagaimana situasi kerja setelah lulus nanti. Oleh karena itu, langkah pertama yang paling penting adalah menemukan tempat pelaksanaan PLA.

Tempat praktek seperti apa yang bagus? Sama dengan saat mencari kerja nanti setelah lulus, tiap mahasiswa punya selera berbeda-beda tergantung minat dan bakat. Tapi menurut saya, idealnya tempat praktek memberikan pengalaman industri sebanyak mungkin (yang berbeda dengan apa yang di dapat di kampus)  dan  menantang (tidak memberikan tugas yang mudah-mudah).  Bahkan saya pernah dengar ada yang praktek juga di luar negeri dan ini bagus sekali karena akan mendapatkan pengalaman budaya juga.

Tidak kalah pentingnya adalah pembimbing di perusahaan. Pembimbing penting karena mengatur pekerjaan yang harus dikerjakan mahasiswa dan menjadi penghubung antara mahasiswa dengan perusahaan. Ada pembimbingnya yang bagus dan memberikan arahan, bantuan pada mahasiswa, tapi ada juga yang kurang. Tapi biasanya pembimbing tidak akan sampai menghalangi atau menjegal, paling-paling hanya cuek saja. Jadi faktor pembimbing sebenarnya bukan faktor utama kegagalan PLA.

Jika perusahaan terlihat dari awal bermasalah maka mahasiswa dapat memilih untuk pindah perusahaan. Jangan paksakan praktek di tempat yang kondisinya memang dari awal sudah buruk. Pernah mahasiswa kami diminta untuk praktek di bagian service hardware yang tidak relevan. Ada juga yang diminta hanya menjadi tukang ketik. Laporkan perusahaan ini pada prodi sehingga dapat masuk ke blacklist.

Setelah mulai praktek di perusahaan, usahakan untuk ikut diberbagai aktivitas yang tidak ditemui di kampus seperti rapat, bertemu dengan client, bersosialisasi dengan pekerja yang lain dsb. Mahasiswa perlu proaktif dalam hal ini, jangan hanya menunggu instruksi dari pembimbing (cuma jangan terlalu memaksa juga).

Pada saat awal, biasanya pembimbing skeptis dengan kemampuan mahasiswa, seringkali mereka memberi tugas yang paling gampang. Mahasiswa kembali harus proaktif dengan mengusulkan task yang lebih menantang, lagipula kalaupun gagal perusahaan tidak akan rugi kan? Tunjukkan kemampuan dan ide yang dimiliki, bahkan contoh-contoh software yang pernah dikembangkan sebelumnya (alasan pentingnya membuat tugas besar yang bagus).  Mahasiswa juga punya peran sebagai duta prodi/universitas, semakin tinggi kemampuan yang ditunjukkan maka semakin besar dampak positif bagi lulusan prodi (lebih mudah diterima kerja di perusahaan ini).  Masalah utama yang paling sering saya temui adalah mahasiwa pasrah (atau bahkan senang) dengan tugas gampang yang diberikan oleh pembimbing. Semakin gampang bukan semakin untung mahasiswa, tapi semakin rugi!

Perusahaan memang seringkali tidak dapat memberikan task yang lebih besar karena khawatir  aset yang dimiliki perusahaan bocor keluar (source code, data) atau khawatir jika modul akan setengah jadi (mahasiswa keburu selesai praktek), dan sulit dilanjutkan oleh pegawai lainnya. Mahasiswa harus pintar mencari celah kesempatan untuk mengerjakan hal yang menarik tapi tidak akan membuat perusahaan khawatir. Peranan pembimbing di prodi penting untuk hal ini. Bahkan kalau perlu, pembimbing dari perusahaan dan pembimbing dari prodi dapat bertemu bersama untuk mendiskusikan solusi yang paling tepat.

Hal lain yang sering dilupakan mahasiswa adalah laporan. Buatlah log berisi catatan kegiatan per hari, sehingga mempermudah mahasiswa saat membuat laporan akhir. Kegiatan seperti rapat, bertemu dengan client juga merupakan aktivitas yang dapat dilaporkan. Buatlah laporan sedetil mungkin sehingga saat penguji membaca, dia akan dapat membayangkan apa yang dikerjakan oleh mahasiswa.

Untuk praktek yang dikerjakan bersama-sama, penting untuk membagi tugas secara jelas. Siapa mengerjakan apa harus tertulis dengan eksplisit. Penguji dapat bertanya sampai ke source code sehingga jangan mengklaim code buatan mahasiswa lain.

Prediksi Hasil Pilpres Menggunakan Media Sosial

20 July 2014 at 07:39 | Posted in Uncategorized | Leave a comment

Setelah membaca artikel WP saya tertarik dengan grafik demografi pemilih setiap capres. Misalnya bahwa suku Jawa memilih Jokowi (tapi Madura berbeda), sebaliknya suku Sunda dan Minang memilih Prabowo. Agama, umur dan jenis pekerjaan juga punya pengaruh. Data lain terkait  ini bisa dilihat di laporan exit poll Indikator.

Saat ini sebenarnya sudah ada analisis tentang pilpres di media sosial, tapi sepertinya baru sebatas sentimen saja. Menurut saya ini masih terlalu kasar dan dangkal untuk dapat menentukan siapa pemenang pilpres. Jika melihat paper yang membahas QC,  distribusi lokasi punya peranan penting.  Sebagai contoh, ini lokasi sampel TPS  yang digunakan  SMRC untuk quickcount.

Jadi untuk bisa memprediksi hasil pilpres berdasarkan media sosial, langkah-langkah yang perlu dilakukan adalah:

  1. Sampling account Twitter/FB  berdasarkan lokasi user tersebut. Ini ditentukan berdasarkan data kepadatan penduduk (atau lebih tepat jumlah calon pemilih per wilayah). Contohnya jumlah account Jabar harusnya lebih banyak dibandingkan Papua.  Cara menentukan lokasi bisa dengan data user profile, atau diambil dari sharing status foursquare/path di account tersebut. Tentu account palsu harus dibuang pada tahap ini.  Untuk topik ini, ada beberapa mahasiswa saya yang sedang membuat skripsi tentang penentuan lokasi pengguna Twitter.
  2. Prediksi data demografi user tersebut, seperti suku, gender,  pendidikan, agama, penghasilan, pekerjaan dst. Mahasiswa saya pernah membuat skripsi tentang prediksi gender dan umur otomatis berdasarkan tweet dengan akurasi sekitar 80%an.
  3. Pastikan  account sample yang digunakan punya distribusi demografi yang sesuai. Soalnya pengguna media sosial condong ke populasi tertentu (muda, pelajar).  Contoh, lebih sulit mencari account orang-orang berumur 50 tahun ke atas dengan pendidikan rendah.
  4. Barulah analisis sentimen dapat dilakukan pada account sample, untuk menentukan pilihan orang tersebut.  Analisis sentimen bisa dilakukan berkali-kali, misalnya 3 bulan sebelum pilpres, setelah debat capres, 1 minggu sebelum pencoblosan dst.

Jadi yang paling penting adalah mendapatkan account FB/Twitter yang representatif sesuai dengan populasi calon pemilih. Setelah itu didapat, banyak hal yang bisa dilakukan. Misalnya analisis pengaruh black campaign, iklan TV, debat capres dan tentunya prediksi hasil yang jauh lebih dulu dari QC.

 

Mengapa saya tidak memilih Prabowo

28 June 2014 at 20:42 | Posted in Uncategorized | 2 Comments

Sebenarnya agak segan menulis hal seperti ini, bahkan saat ini saya cuti dulu dari FB sampai pilpres selesai. Kampanye dan saling serang sudah begitu parahnya sehingga kedua pihak sudah seperti suporter fanatik sepakbola yang berantem tanpa alasan jelas. Lalu kenapa saya masih tulis disini? Blog adalah catatan pemikiran yang akan dapat dibaca dalam jangka panjang (terutama via situs seperti webarchive). Anak dan cucu bahkan cicit saya mudah-mudahan akan membaca posting ini 10-50 tahun ke depan. Mempelajari masa lalu penting agar tidak mengulangi kesalahan yang sama.

Saya juga bukan pendukung Jokowi, menurut saya dia belum siap untuk sekarang, masih terlalu dini. Tapi mungkin dia satu-satunya yang bisa menjadi lawan tangguh bagi Prabowo untuk saat ini.

Kembali ke judul, jadi kenapa saya tidak memilih Prabowo?  Jawabannya satu: karena dia terlibat dalam penculikan aktivis di tahun 98.  Ada dua hal yang selanjutnya perlu dibahas, apa ini benar?  kedua, kenapa ini jadi penting, bahkan lebih penting dari isu-isu lain?

Saya tidak mau berspekulasi untuk hal yang lain (kerusuhan/kudeta dst), kasus di kisaran 98 masih simpang siur. Mungkin nanti akan seperti G30S/PKI yang mulai cerah 40 tahun setelah kejadian, saat para pemainnya intinya sudah mau menulis memoar.  Saya hanya melihat fakta penculikan yang melibatkan 9 aktivis (yang kembali hidup). Ini sudah diputuskan oleh DKP dan juga sudah didiakui oleh Prabowo (http://www.tempo.co/read/news/2013/10/28/078525234/Pernah-Diculik-Pius-Prabowo-Tak-Bersalah).  Tentang perbedaan versi bahwa ini atas perintah atasan (versi Prabowo) atau karena inisiatif sendiri (versi DKP) dan nasib 13 orang hilang lain, untuk saat ini tidak bisa dipastikan versi mana yang benar.

Nah sekarang  kenapa ini penting?

Karena kalau dengan alasan “keamanan”, “keselamatan bangsa”, “demi orang banyak” semua cara bisa dihalalkan, artinya sudah tidak ada batas lagi .  Bayangkan seperti bermain bola tanpa batasan, tanpa wasit,  orang boleh menjegal, memukul, menusuk, mencekik dst, sehingga hukum rimbalah yang berlaku. Ini yang berlaku saat Orde Baru. Polisi, jaksa dan hakim lemah,  legislatif tidak berfungsi. Semua kekuasaan dipusatkan di satu tangan: Pak Harto.  Dampaknya juga terasa pada kebijakan-kebijakan lain, termasuk kebijakan ekonomi, bahkan agama (kebijakan satu azas, larangan berjilbab di sekolah)

Seperti halnya Tiongkok, Singapura dan Malaysia, model diktator  ada manfaatnya. Negara bisa stabil, kebijakan bisa cepat dieksekusi tanpa banyak pertentangan.  Tapi ini juga menyimpan bom waktu. Contohnya  bisa dilihat Uni Soviet, Irak dan Mesir ( Tiongkok menurut saya akan mengalami hal yang sama nanti). Masalah korupsi di Indonesia juga bukan terjadi semalam, tapi dipupuk selama puluhan tahun. Bahkan setelah 16 tahun setelah reformasipun, sektor hukum dan legislatif kita juga masih lemah. Sudah ada perbaikan, tapi lambat ibarat orang yang dipasung berpuluh-puluh tahun dan baru belajar berjalan. Beruntung Pak Harto (seperti halnya Sukarno) bijak untuk mundur baik-baik tanpa menimbulkan perang saudara.

Tentu Suharto berbeda dengan Prabowo. Suharto naik menjadi presiden saat masih berumur 45 dan Indonesia di tahun 1966 dalam kondisi kacau. Suharto juga ahli strategi yang dengan jenius dan sabar pelan-pelan memusatkan kekuasaan di tanganya. Prabowo kalaupun jadi presiden sudah berumur 62 dan Indonesia di 2014 dalam kondisi baik. Kita juga sudah 16 tahun melewati reformasi sehingga akan sulit mencabut hal-hal seperti kebebasan pers.  Tapi, tetap saja ini resiko yang tidak sepadan. Kita sudah mulai bisa berjalan walaupun masih tertatih-tatih, saya yakin sebentar lagi kita bisa berlari (sebentar dalam usia negara, kira-kira 20thn lagi). Jangan buat kita jadi merangkak lagi.

 

Update 21 Juli pasca pemilu:

Perkiraan saya benar mengenai menghalalkan segala cara, dimulai dengan membuat quick count abal-abal tandingan, lalu minta KPU mengundurkan waktu pengumuman, mengancam akan mempidanakan KPU, sampai dengan minta hitung suara ulang (anehnya tidak protes kecurangan langsung setelah pencoblosan). Ini hal yang baru dalam pilpres, biasanya yang tidak setuju akan melewati mekanisme pengumuman KPU dan menggugat via MK.  Sangat mengerikan menurut saya, bahkan sebelum KPU mengumumkanpun sudah mulai dicoba digoyang.  Bayangkan kalau Prabowo jadi presiden dan menghadapi pemilu 2019 sebagai incumbent, apa saja yang akan dilakukan olehnya?

Update 22 Juli:
Prabowo “menarik diri dari proses” dan mengatakan proses pilpres cacat. Bukan hasil tapi keseluruhan proses! Banyak orang dibuat bengong, bahkan sampai Hatta-pun menjaga jarak. Ini sesuatu yang baru terjadi lagi dalam sejarah piplres, kalah W.O. (walk out)?

Blokir Situs di Indonesia

18 May 2014 at 13:30 | Posted in Uncategorized | 2 Comments

Blokir situs di Indonesia dengan alasan pornografi sudah berlangsung cukup lama, tapi yang membuat jadi ribut baru-baru ini adalah mulai menjalarnya blokir ke situs-situs yang kategorinya bukan eksplisit pornografi seperti Vimeo dan Reddit.  Saya tidak mau berpanjang-panjang di masalah pornografinya karena nanti ujung-ujungnya jadi debat kusir hehe.. karena jangankan kita, Apple Store saja sulit dan sering diprotes dalam menentukan app mana yang mengandung pornografi mana yang tidak. Facebook juga pernah ramai dengan urusan foto ibu menyusui.

Yang mau saya tulis disini, karena sepertinya jarang ditulis orang adalah blokir yang dilakukan Indonesia itu hanya efektif untuk orang awam dan anak-anak kecil tapi sangat tidak efektif bagi remaja (remaja disini kelas 6 SD ke atas)  dan orang yang memang niat mengakses materi pornografi. Bagi yang niat, blokir di Indonesia itu seperti menggunakan triplek untuk menahan kereta api.  Mengapa gampang ditembus? jawabannya karena perang antara sistem filter China (Great Firewall) dengan masyarakat hacker + pihak yang ingin internet tetap bebas di China. China mengeluarkan biaya sangat besar untuk memblokir berbagai situs, mulai dari Youtube, Facebook, Twitter sampai dengan Reuters karena penting untuk kelangsungan hidup rezimnya (sama dengan Pak Harto yang membreidel berbagai media di jaman orba). Pihak yang lain juga sama kerasnya berjuang agar filter tersebut tembus, bahkan saya pribadi percaya pihak intelijen negara barat juga berperan karena butuh resources tidak sedikit untuk menangkal filter ini. Jadi ini perang skala besar. Efeknya adalah banyak tersedia tools yang efektif dan mudah digunakan untuk menangkal blokir. Untuk China saja dapat ditembus dengan tools tersebut apalagi blokir Indonesia yang lebih sederhana. Jadi kecuali Indonesia mau seperti China yang  menghabiskan dana dan tenaga yang sangat besar,  lebih baik tidak perlu ikut-ikutan sistem ini.

Kesimpulannya,  blokir situs eksplisit pornografi tetap diperlukan untuk mencegah anak kecil atau orang awam masuk secara tidak sengaja. Tapi untuk situs lain lebih baik tidak, karena selain tidak efektif, maka semua situs  termasuk Youtube, FB, Google, Wikipedia bahkan WordPress juga harus diblokir. Karena ya itu tadi, definisi pornografi berbeda untuk setiap budaya dan agama.  Kita teriak porno mereka bilang seni dan jadinya debat kusir lagi yang tidak penting. Kenapa debat yang tidak penting? karena orang yang niat mengakses situs pornografi tetap saja bisa mengakses dengan gampang hehe (bahkan mungkin mereka sedang menertawai orang-orang yang sedang debat kusir ini).

Lalu stop menggadang-gadang blokir sebagai alat yang efektif untuk mencegah pornografi.  Itu hanya memberikan rasa aman palsu dan menyesatkan.  Dengan analogi triplek vs kereta  tadi, mengandalkan blokir seperti memberikan triplek ke anak, lalu bilang “nak kalau kebetulan kamu ada di rel kereta dan ada kereta api akan lewat, letakkan triplek ini di depan kamu”. Fatal kan? Lebih baik ajarkan agar  anak berhati-hati kalau disekitar rel kereta api, dan kalaupun harus menyebrang, lihat kanan dan kiri dulu (sambil dengarkan suara kereta), atau lebih baik lagi gunakan jembatan penyebrangan kalau ada.  Ajarkan anak atau siswa untuk bisa memblokir diri sendiri, itu lebih penting.

LibGDX untuk membuat Game pada Android (Modul Tutorial LibGDX)

13 October 2013 at 07:42 | Posted in android, kuliah | 1 Comment
Tags: , ,

Update April 2015: tutorial libgdx di blog saya yang lain.

LibGDX  (libgdx.badlogicgames.com) adalah framework untuk membuat game,  visualisasi dan simulasi.  Kelebihan LibGDX diantaranya:

  1. Multiplatform. Dapat menghasilkan app untuk desktop (Win, Linux, Max), Android, iOS dan web dengan mudah.
  2. Free dan opensource (lisensi Apache 2.0).
  3. Basisnya Java.
  4. Tidak perlu mengetahui Android SDK.  Anda dapat membuat game di Android walaupun belum pernah membuat app di Android sebelumnya, tentunya asal mengerti Java.
  5. Tidak perlu menggunakan emulator!  Proses pengembangan jadi jauh lebih cepat. Jalankan project di desktop dan nanti setelah selesai baru jalankan versi Androidnya tanpa tambahan code.
  6. Kinerja bagus, melebihi beberapa framework lain (pembahasan tentang ini: http://www.sparkrift.com…l)
  7. Menyediakan banyak fitur yang memudahkan programmer membuat game seperti box2D, Scene2D, Bullets  3D dan lainnya.
  8. Dokumentasi lumayan dan forum-nya aktif.

Saya membuat modul praktikum untuk kuliah game programming di Ilkom UPI. Lisensi tutorialnya adalah creative commons dan formatnya MS Word, jadi silahkan didistribusikan, dimodifikasi asal nama saya jangan dibuang.  Bagi yang berminat, dokumennya dapat didownload di: yuliadi.com/ilkom  (cari dokumen yang diawali “tutorial_libgdx”)

Perlukah memanaskan mobil lama-lama?

11 August 2013 at 10:07 | Posted in Uncategorized | 2 Comments

Memanaskan mobil sepertinya sudah menjadi kebiasaan. Bagi yang memiliki garasi jauh dari rumah dan tetangga ini tidak menjadi masalah, tetapi bagi yang tinggal di daerah padat dan rumah kecil ini bisa menimbulkan polusi yang merugikan orang-orang disekitar mobil. Apalagi catalytic converter yang berfungsi untuk menyaring zat berbahaya dari buangan kendaraan  baru berfungsi optimal pada suhu 650 derajat celcius. Belum lagi kalau mempertimbangkan bahan bakar yang dibuang percuma.

Setelah saya membaca manual buku mobil saya (Picanto), ternyata hanya diperlukan 10-20 detik untuk memanaskan mobil, dengan perkecualian untuk cuaca yang sangat dingin yang tentunya  tidak pernah terjadi di Indonesia. Menurut saya ini juga berlaku untuk mobil-mobil yang lain, diluar mobil berumur tua.  Jika ragu, coba baca manualnya.

Image

Implementasi Game/Animation Loop di Android Bagian 2

4 August 2013 at 00:26 | Posted in android | 1 Comment

Pada posting sebelumnya, telah dibahas implementasi game loop di Android.  Tetapi implementasi tersebut masih memiliki kelemahan. JIka jumlah objek banyak sehingga proses update posisi membutuhkan waktu lama,  ditambah lagi delay yang fix 0.2 detik maka loop akan berlangsung lebih lama dari seharusnya. Kecepatan animasi juga dapat berbeda untuk berbagai smartphone.

Ada dua cara untuk memperbaiki: pertama delay dilakukan secara dinamik, semakin lambat smartphone, semakin lambat loop maka sleep juga akan semakin sebentar. Yang kedua, jika loop membutuhkan waktu lebih lama dari minimal waktu yang ditentukan, maka untuk mengejar ketertinggalan update posisi akan dilakukan tanpa ditampilkan (hanya updateposisi tanpa draw). Penjelasan lebih rinci dapat dilihat di http://obviam.net/index.php/the-android-game-loop/   Kode dibawah juga saya adaptasi dari contoh pada web tersebut.  Berikut kode-nya, banyak komentar yang saya tambahkan pada kode ini, semoga bisa lebih memperjelas.

import com.example.animasicanvas2.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.SurfaceHolder;

//menggunakan runnable, karena hanya run yang dibutuhkan untuk dioverride
//baca: http://manikandanmv.wordpress.com/tag/extends-thread-vs-implements-runnable/
//tentang bedanya extends thread vs runnable

//sebagian kode diambil dari : http://obviam.net/index.php/the-android-game-loop/

public class GameRunnable implements Runnable {

	 //TAMBAHAN==========

	// nilai frame per detik (fps) yang diinginkan
	// jika 25 FPS artinya satu loop yang berisi update+draw akan dieksekusi setiap 1/25 detik
	private final static int 	MAX_FPS = 25;

	// frame period, waktu satu loop dieksekusi dalam satuan mili detik (ms)
	// jadi kalau 25 FPS, maka frame perode adalah 1/25 detik atau 1000/25 ms = 40ms
	private final static int	FRAME_PERIOD = 1000 / MAX_FPS;

	// jumlah frame yang boleh dilewat saat proses update posisi terlalu lama
	// Contoh: untuk 25 FPS, satu loop berarti diekkseskusi 40ms
	// misalnya jumlah objek yang harus diupdate posisinya banyak sehingga
	// melewati 40ms, maka akan dilakukan updateposisi *TANPA* proses draw (di-skip).
	// kenapa spt itu? karena lebih baik FPS turun daripada posisi objek berantakan.
	// konstanta berikut menyatakan berapa frame proses draw boleh di-skip
	// detilnya silahkan lihat method run()
	private final static int	MAX_FRAME_SKIPS = 5;

	 //jika true, loop di run() berakhir
	 boolean mRun=false;
	 float posX=10;
	 float posY=100;
	 Bitmap bmp;
	 private Paint cat = new Paint();

	 //akses ke surface dan canvas
	 private SurfaceHolder mSurfaceHolder;

	 //akses ke context (untuk ambil resource)
	 Context mContext;

	 long lastTick;

	 private void updatePosisi(long tick) {
		 //1 tick = 1/25 detik (untuk 25FPS)
		 //update akan dilakukan jika sudah berselang 1 detik dari update terakhir
		 if (tick-lastTick > 25) {
			 //geser ke kiri dan kalau sudah max, kembali ke awal
			 posX= posX+10;
			 if (posX>200) {
				 posX=10;
			 }
			 lastTick = tick;
		 }
	 }

	 //siapkan resources berupa bitmap,
	 //ambil bitmap icon launcher supaya mudah
	 public GameRunnable(SurfaceHolder vSurfaceHolder, Context vContext) {
		  mSurfaceHolder = vSurfaceHolder;
		  mContext = vContext;
		  Resources res = mContext.getResources();
		  bmp = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
	 }

	 //bersihkan layar dan gambar objek
	 public void doDraw(Canvas c) {
		//canvas perlu dicek apakah null, karena pada saat
		 //user pindah ke activity lain (user tekan home), c bisa
		 //berisi null (proses shutdown belum selesai dan
		 //thread masih jalan, tapi canvas sudah didestroy)
		 if (c!=null) {
			//clear screen
			c.drawColor(Color.WHITE);
			//gambar bitmap
			c.drawBitmap(bmp,posX,posY,cat);
		}
	 }

	 @Override
     public void run() {

		 //TAMBAHAN
		 // waktu mulai awal loop
		 long beginTime;

		 // waktu real yang dibutuhkan untuk loop
		 long timeDiff;

		 // waktu tidur, misal FPS 25, berarti 1 loop = 40ms. Jika timeDiff = 30 ms, maka
		 // sleeptime 10ms (sisa waktu digunakan untuk sleep)
		 // tapi jika timeDiff 60ms, maka sleepTime akan bernilai negatif (-
		 int sleepTime;

		 // jumlah frame (draw) yang sudah di-skip, lihat penjelasan tentang
		 // MAX_FRAME_SKIPS diatas
		 int framesSkipped;

		 //satuan waktu update, setiap update nilai tick akan bertambah
		 //jika objek dalam suatu game banyak, nilai tick digunakan sebagai waktu global
		 //sehingga setiap objek sinkron
		 long tick = 0;

		 //loop forever selama tidak dishutdown (mRun diset false)
		 while (mRun) {
             Canvas c = null;
             try {
                 c = mSurfaceHolder.lockCanvas(null);
                 //lock surface agar tidak diakses thread lain dulu
                 synchronized (mSurfaceHolder) {
                     //TAMBAHAN
                	 //catat waktu skr
                	 beginTime = System.currentTimeMillis();
     				 framesSkipped = 0;

                	 updatePosisi(tick);
                	 tick++;
                     doDraw(c);

                     //TAMBAHAN
                     //hitung waktu yg dibutuhkan untuk satu loop
                     timeDiff = System.currentTimeMillis() - beginTime;
     				 //hitung waktu tidur, kalau positif artinya loop
                     //lebih cepat dari max FPS dan thread akan tidur
                     //tapi kalau nilainya negatif artinya loop berjalan
                     //lebih dari waktu seharusnya shg akan dilakukan penyesuaian
                     //yaitu update posisi tanpa draw.
     				 sleepTime = (int)(FRAME_PERIOD - timeDiff);

     				 //sleep sebanyak sleepTime kalau masih ada siswa waktu (sleeptime>0)
     				 if (sleepTime > 0) {
	     				 try {
	     						Thread.sleep(sleepTime);
	     				 } catch (InterruptedException e) {
	     						e.printStackTrace();
	     						Log.e("yw","error saat mencoba sleep"+e.getMessage());

	     				 }
     				 }

     				 //jika sleeptime negatif (proses update dan draw terlalu lama)
     				 //maka masuk loop berikut
     				 //di dalam loop update dilakukan *TANPA* draw
     				 while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {

    					// update posisi saja
     					updatePosisi(tick);
     					tick++;
    					//tambah, jika sleepTime>=0 keluar
    					sleepTime += FRAME_PERIOD;

    					//jumlah draw yang di-skip, dibatasi agar FPS tidak terlalu
    					//drop
    					framesSkipped++;
    				 }

                 }
             } finally {
                 //pastikan diunlock
                 if (c != null) {
                     mSurfaceHolder.unlockCanvasAndPost(c);
                 }
             }
         }
     }

	//jika diset false maka akan shutdown (lihat method run())
	public void setRunning(boolean b) {
		mRun = b;
	}
}

Implementasi Game/Animation Loop di Android

2 June 2013 at 13:49 | Posted in android | 1 Comment
Tags: ,

Bermula dari pertanyaan mahasiswa, ternyata setelah cukup lama saya mencari belum ada penjelasan yang menurut saya enak mengenai loop untuk animasi atau game berbasis canvas (game loop). Akhirnya saya coba sendiri menggunakan dasar contoh LunarLander yang merupakan bagian dari SDK samples dengan lumayan banyak modifikasi.

Game loop pada intinya adalah:

while (true) {
	updatePosisiObjek();
	gambarObjek();
}

Contoh berikut merupakan implementasi loop untuk animasi sederhana.  Jika anda belum mengerti dasar-dasar Android, anda dapat mendownload modul pengantar android di yuliadi.com/ilkom terutama bagian canvas.

Pada app ini terdapat tiga class, pertama GameRunnable yang berfungsi untuk mengatur gerakan dan menggambar di canvas. Kedua adalah GameView yang merupakan turunan dari SurfaceView yang menyediakan canvas yang akan digambar. GameView ini juga bertugas membuat dan mematikan thread (thread ini diisi GameRunnable). Terakhir adalah activity utama (MainActivity). Penjelasan lebih detil dapat dilihat di source codenya langsung.

Source code untuk class GameRunnable:

package edu.upi.cs.yudiwbs.animasicanvas2;

import com.example.animasicanvas2.R;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.SurfaceHolder;

//menggunakan runnable, karena hanya run yang dibutuhkan untuk dioverride
//baca: http://manikandanmv.wordpress.com/tag/extends-thread-vs-implements-runnable/
//tentang bedanya extends thread vs runnable
public class GameRunnable implements Runnable {

	 //jika true, loop di run() berakhir
	 boolean mRun=false;
	 float posX=10;
	 float posY=100;
	 Bitmap bmp;
	 private Paint cat = new Paint();

	 //akses ke surface dan canvas
	 private SurfaceHolder mSurfaceHolder;

	 //akses ke context (untuk ambil resource)
	 Context mContext;

	 private void updatePosisi() {
		 //geser ke kiri dan kalau sudah max, kembali ke awal
		 posX= posX+10;
		 if (posX>200) {
			 posX=10;
		 }

		 //tidur 0.2 detik, agar animasi tdk terlalu cepat
		 try {
				Thread.sleep((long)(1000*0.2));
		 } catch (InterruptedException e) {
				e.printStackTrace();
				Log.e("yw","error saat mencoba sleep"+e.getMessage());

		 }
	 }

	 //siapkan resources berupa bitmap, ambil bitmap icon launcher supaya mudah
	 public GameRunnable(SurfaceHolder vSurfaceHolder, Context vContext) {
		  mSurfaceHolder = vSurfaceHolder;
		  mContext = vContext;
		  Resources res = mContext.getResources();
		  bmp = BitmapFactory.decodeResource(res, R.drawable.ic_launcher);
	 }

	 //bersihkan layar dan gambar objek
	 public void doDraw(Canvas c) {
		 //canvas perlu dicek apakah null, karena pada saat
		 //user pindah ke activity lain (user tekan home), c bisa
		 //berisi null (proses shutdown belum selesai dan
		 //thread masih jalan, tapi canvas sudah didestroy)
		 if (c!=null) {
			//clear screen
			c.drawColor(Color.WHITE);
			//gambar bitmap
			c.drawBitmap(bmp,posX,posY,cat);
		}
	 }

	 @Override
     public void run() {
		 //loop forever selama tidak dishutdown (mRun diset false)
         while (mRun) {
        	 Log.i("yw","looping...."); //hapus log ini kalau tidak mendebug
             Canvas c = null;
             try {
                 c = mSurfaceHolder.lockCanvas(null);
                 //lock surface agar tidak diakses thread lain dulu
                 synchronized (mSurfaceHolder) {
                     updatePosisi();
                     doDraw(c);
                 }
             } finally {
                 //pastikan diunlock
                 if (c != null) {
                     mSurfaceHolder.unlockCanvasAndPost(c);
                 }
             }
         }
     }

	//jika diset false maka akan shutdown (lihat method run())
	public void setRunning(boolean b) {
		mRun = b;
	}
}

Sedangkan code untuk class GameView adalah

package edu.upi.cs.yudiwbs.animasicanvas2;

import android.content.Context;

import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

//surfaceView digunakan karena GUI akan seriung diupdate
//dan cepat untuk animasi
public class GameView extends SurfaceView implements SurfaceHolder.Callback  {

	public Thread mThread;
	private GameRunnable gr;

	//buat thread dan jalankan
	public void startThread() {
		//objek GameRunnable jadi parameter
		mThread = new Thread(gr);
		gr.setRunning(true);
	    mThread.start();

	}

	public void shutDownThread() {
		Log.i("yw","shutdown thread mulai");
		boolean retry = true;
        gr.setRunning(false);  //matikan,

        //loop terus sampai thread berhenti karena
        //setRunning(false) tidak menghentikan seketika
        //coba lihat method GameThread.run()
        while (retry) {
            try {
                mThread.join();
                retry = false;
            } catch (InterruptedException e) {
            }
        }
        Log.i("yw","shutdown selesai");
	}

	public GameView(Context context) {
		super(context);
		SurfaceHolder holder = getHolder();
		holder.addCallback(this);
		gr = new GameRunnable(holder,context);
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		Log.i("yw","jalankan thread !!");
		startThread();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		shutDownThread();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// bisa digunakan untuk memberi tahu GameRunnable ada perubahan dimensi
		// surface (misal dirotate)
	}
}

Dan terakhir adalah MainActivity

package edu.upi.cs.yudiwbs.animasicanvas2;

import com.example.animasicanvas2.R;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

GameView gv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		gv= new GameView(this);
		setContentView(gv);
	}

	 @Override
	 protected void onPause() {
	    super.onPause();
	    //nantinya perlu diisi dengan penyimpanan state
	    //melalui bundle
	 }

	 @Override
	protected void onResume() {
		super.onResume();
		//nantinya perlu diisi dengan load state
	 }

}

Kode diatas masih memiliki kelemahan, perhatikan penggunaan delay 0.2 ms pada updatePosisi() di GameRunnable. Jika suatu saat app ini diinstall pada smartphone yang lambat dan memiliki ratusan objek yang harus diupdate posisinya maka animasi akan berjalan semakin lambat. Pada kasus sepeert itu seharusnya delay dikurangi. Posting berikutnya akan membahas cara untuk mengatasi hal ini.

Salah satu hal yang perlu ditangani adalah saat pengguna pindah ke app lain dan kembali. Misalnya dengan menekan home, pindah ke app lain lalu kembali ke app animasi ini. Setiap pengguna pindah ke app lain, maka thread harus distop agar tidak memakan resources. Setelah mencoba beberapa kali dan memperhatikan hasil log, saat home ditekan, maka canvas pada doDraw dapat bernilai null. Jadi saat thread masih berjalan canvas dapat bernilai null. Ini sebabnya perlu ada pengecekan kondisi if (c!=null) pada method GameRunnable.doDraw (baris 63). Pada app LunarLander yang asli, tidak ada pengecekan ini dan terjadi error saat user menekan home.

Hal yang lain, saat home ditekan, maka GameView.surfaceDestroyed pasti akan dipanggil. Tadinya saya mengira sistem tidak akan men-destroy kecuali kalau membutuhkan. Ini menyebabkan proses mematikan thread dilakukan bukan di activity.onPause tapi cukup di method surfaceDestroyed. Tentu dalam kondisi sebenarnya onPause dan onResume perlu ditangani untuk menyimpan state. Sebagai contoh, saat app ini dijalankan dan kemudian device dirotasi maka app akan mulai dari awal lagi (nilai GameRunnable.posX hilang).

« Previous PageNext Page »

Create a free website or blog at WordPress.com.
Entries and comments feeds.