class Keyboard { // digunakan untuk melacak input keyboard
Boolean holdingUp,holdingRight,holdingLeft,holdingSpace;
Keyboard() {
holdingUp=holdingRight=holdingLeft=holdingSpace=false;
}
/* Cara Processing, dan banyak bahasa pemrograman / lingkungan,
* berkaitan dengan kunci yang memperlakukan mereka seperti kejadian (sesuatu bisa terjadi saat turun, atau ketika naik.
* Karena kita ingin memperlakukan mereka seperti tombol - memeriksa "itu ditekan sekarang?" -
* Kita perlu menggunakan peristiwa-peristiwa ditekan dan dilepas untuk memperbarui beberapa
* nilai-nilai palsu benar bahwa kita dapat memeriksa di tempat lain./
void pressKey(int key,int keyCode) {
if(key == 'r') { // tidak akan pernah ditekan, sehingga tidak dibutuhkan Boolean untuk melacak
if(gameWon()) { // jika kondisi permainan menang
resetGame(); // kemudian R key mereset permainan
}
}
if (keyCode == UP) {
holdingUp = true;
}
if (keyCode == LEFT) {
holdingLeft = true;
}
if (keyCode == RIGHT) {
holdingRight = true;
}
if (key == ' ') {
holdingSpace = true;
}
}
void releaseKey(int key,int keyCode) {
if (keyCode == UP) {
holdingUp = false;
}
if (keyCode == LEFT) {
holdingLeft = false;
}
if (keyCode == RIGHT) {
holdingRight = false;
}
if (keyCode == ' ') {
holdingSpace = false;
}
}
}
Coding untuk Player
class Player {
PVector position,velocity; // Pvector berisi dua sumbu, x and y
Boolean isOnGround; // Digunakan untuk melacak apakah pemain ada ditanah. Berfungsi untuk kontrol dan animasi
Boolean facingRight; // Digunakan untuk menentukan arah terakhir pemain pindah. Digunakan untuk memutar pemain.
int animDelay; // Penghitung waktu mundur antara update animasi
int animFrame; // Melacak frame animasi untuk pemain saat ditampilkan
int coinsCollected; // counter untuk menjaga penghitungan pada berapa banyak koin pemain telah dikumpulkan
static final float JUMP_POWER = 11.0; // seberapa keras sentakan pemain pada lompatan
static final float RUN_SPEED = 5.0; // kekuatan pergerakan pemain di tanah
static final float AIR_RUN_SPEED = 2.0; // seperti kecepatan berlari, tetapi digunakan untuk kontrol sementara di udara
static final float SLOWDOWN_PERC = 0.6; // gesekan dari tanah. Dikalikan dengan kecepatan x setiap frame
static final float AIR_SLOWDOWN_PERC = 0.85; // daya tahan di udara, jika kontrol udara memungkinkan kecepatan yang luar biasa
static final int RUN_ANIMATION_DELAY = 3; // berapa banyak siklus permainan berjalan antara update animasi?
static final float TRIVIAL_SPEED = 1.0; // jika dibawah kecepatan ini, pemain dianggap berdiri diam
Player() { // konstruktor, dipanggil secara otomatis ketika pemain dibuat
isOnGround = false;
facingRight = true;
position = new PVector();
velocity = new PVector();
reset();
}
void reset() {
coinsCollected = 0;
animDelay = 0;
animFrame = 0;
velocity.x = 0;
velocity.y = 0;
}
void inputCheck() {
// Keyboard bendera ditetapkan oleh keyPressed / keyReleased di main .pde
float speedHere = (isOnGround ? RUN_SPEED : AIR_RUN_SPEED);
float frictionHere = (isOnGround ? SLOWDOWN_PERC : AIR_SLOWDOWN_PERC);
if(theKeyboard.holdingLeft) {
velocity.x -= speedHere;
} else if(theKeyboard.holdingRight) {
velocity.x += speedHere;
}
velocity.x *= frictionHere; // penyebab pemain untuk terus kehilangan kecepatan
if(isOnGround) { // pemain hanya dapat melompat jika masih diatas tanah
if(theKeyboard.holdingSpace || theKeyboard.holdingUp) { // keduanya arah keatas atau bar spasi menyebabkan pemain melompat
sndJump.trigger(); // memainkan suara
velocity.y = -JUMP_POWER; // mengatur kecepatan vertikal
isOnGround = false; // menandai pemain telah meninggalkan lapangan, tidak dapat melompat lagi saat ini
}
}
void checkForWallBumping() {
int guyWidth = guy_stand.width; // pikirkan ukuran pemain berdiri sebagai ukuran fisik pemain
int guyHeight = guy_stand.height;
int wallProbeDistance = int(guyWidth*0.3);
int ceilingProbeDistance = int(guyHeight*0.95);
/* Because of how we draw the player, "position" is the center of the feet/bottom
* To detect and handle wall/ceiling collisions, we create 5 additional positions:
* leftSideHigh - left of center, at shoulder/head level
* leftSideLow - left of center, at shin level
* rightSideHigh - right of center, at shoulder/head level
* rightSideLow - right of center, at shin level
* topSide - horizontal center, at tip of head
* These 6 points - 5 plus the original at the bottom/center - are all that we need
* to check in order to make sure the player can't move through blocks in the world.
* This works because the block sizes (World.GRID_UNIT_SIZE) aren't small enough to
* fit between the cracks of those collision points checked.
*/
// digunakan sebagai penyelidik untuk mendeteksi pelarian ke dinding, langit-langit
PVector leftSideHigh,rightSideHigh,leftSideLow,rightSideLow,topSide;
leftSideHigh = new PVector();
rightSideHigh = new PVector();
leftSideLow = new PVector();
rightSideLow = new PVector();
topSide = new PVector();
// menyelidiki update dinding
leftSideHigh.x = leftSideLow.x = position.x - wallProbeDistance; // tepi kiri pemain
rightSideHigh.x = rightSideLow.x = position.x + wallProbeDistance; // tepi kanan pemain
leftSideLow.y = rightSideLow.y = position.y-0.2*guyHeight; // tinggi lompatan
leftSideHigh.y = rightSideHigh.y = position.y-0.8*guyHeight; // tinggi bahu
topSide.x = position.x; // tengah-tengah pemain
topSide.y = position.y-ceilingProbeDistance; // atas orangnya
//jika ada tepi pemain ada di dalam killblock merah, ulang putaran
if( theWorld.worldSquareAt(topSide)==World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(leftSideHigh)==World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(leftSideLow)==World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(rightSideHigh)==World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(rightSideLow)==World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(position)==World.TILE_KILLBLOCK) {
resetGame();
return; // kemungkinan tabrakan akan menjadi tidak relevan, keluar fungsi sekarang }
// kondisi berikut hanya memeriksa tabrakan dengan setiap benjolan
// tergantung pada dimana penyelidikan telah bertabrakan, kita mendorong pemain kembali ke arah yang berlawanan
if( theWorld.worldSquareAt(topSide)==World.TILE_SOLID) {
if(theWorld.worldSquareAt(position)==World.TILE_SOLID) {
position.sub(velocity);
velocity.x=0.0;
velocity.y=0.0;
} else {
position.y = theWorld.bottomOfSquare(topSide)+ceilingProbeDistance;
if(velocity.y < 0) {
velocity.y = 0.0;
}
}
}
if( theWorld.worldSquareAt(leftSideLow)==World.TILE_SOLID) {
position.x = theWorld.rightOfSquare(leftSideLow)+wallProbeDistance;
if(velocity.x < 0) {
velocity.x = 0.0;
}
}
if( theWorld.worldSquareAt(leftSideHigh)==World.TILE_SOLID) {
position.x = theWorld.rightOfSquare(leftSideHigh)+wallProbeDistance;
if(velocity.x < 0) {
velocity.x = 0.0;
}
}
if( theWorld.worldSquareAt(rightSideLow)==World.TILE_SOLID) {
position.x = theWorld.leftOfSquare(rightSideLow)-wallProbeDistance;
if(velocity.x > 0) {
velocity.x = 0.0;
}
}
if( theWorld.worldSquareAt(rightSideHigh)==World.TILE_SOLID) {
position.x = theWorld.leftOfSquare(rightSideHigh)-wallProbeDistance;
if(velocity.x > 0) {
velocity.x = 0.0;
}
}
}
void checkForCoinGetting() {
PVector centerOfPlayer;
// kami menggunakan ini untuk memeriksa koin tumpang tindih di tengah pemain
// (ingat bahwa "posisi" adalah melacak tengah bawah kaki)
centerOfPlayer = new PVector(position.x,position.y-guy_stand.height/2);
if(theWorld.worldSquareAt(centerOfPlayer)==World.TILE_COIN) {
theWorld.setSquareAtToThis(centerOfPlayer, World.TILE_EMPTY);
sndCoin.trigger();
coinsCollected++;
}
}
void checkForFalling() {
/ / Jika kita berdiri pada ubin kosong atau koin, kita tidak berdiri pada apa pun. Jatuh! if(theWorld.worldSquareAt(position)==World.TILE_EMPTY ||
theWorld.worldSquareAt(position)==World.TILE_COIN) {
isOnGround=false;
}
if(isOnGround==false) { // tidak di tanah ?
if(theWorld.worldSquareAt(position)==World.TILE_SOLID) { // ada di kotak padat?
isOnGround = true;
position.y = theWorld.topOfSquare(position);
velocity.y = 0.0;
} else { // jatuh
velocity.y += GRAVITY_POWER;
}
}
}
void move() {
position.add(velocity);
checkForWallBumping();
checkForCoinGetting();
checkForFalling();
}
void draw() {
int guyWidth = guy_stand.width;
int guyHeight = guy_stand.height;
if(velocity.x<-TRIVIAL_SPEED) {
facingRight = false;
} else if(velocity.x>TRIVIAL_SPEED) {
facingRight = true;
}
pushMatrix(); // lets us compound/accumulate translate/scale/rotate calls, then undo them all at once
translate(position.x,position.y);
if(facingRight==false) {
scale(-1,1); // membalik horizontal dengan skala horisontal dengan -100%
}
translate(-guyWidth/2,-guyHeight); // menggambar gambar berpusat pada kaki karakter
if(isOnGround==false) { // jatuh atau melompat
image(guy_run1, 0,0); // pose ini berjalan cukup baik terlihat saat di udara
} else if(abs(velocity.x)<TRIVIAL_SPEED) { // not moving fast, i.e. standing
image(guy_stand, 0,0);
} else { // berjalan. Bernyawa.
if(animDelay--<0) {
animDelay=RUN_ANIMATION_DELAY;
if(animFrame==0) {
animFrame=1;
} else {
animFrame=0;
}
}
if(animFrame==0) {
image(guy_run1, 0,0);
} else {
image(guy_run2, 0,0);
}
}
popMatrix(); // Membatalkan semua penerjemahan / skala / memutar panggilan sejak pushMatrix sebelumnya dalam fungsi ini
}
}