Assalamualaikum Wr.Wb
perkenalkan kami adalah developer game indie yang sedang belajar, kami akan mengerjakan sebuah tugas softskill membuat game, software yang kami pakai adalah processing.
RANCANGAN PROGRAM
1.1. Rancangan Aplikasi
Dalam
aplikasi ini Storyboard menerangkan
tentang perjalanan user dalam menggunakan
aplikasi adalah sebagai berikut :
Pada Storyboard di atas, ketika user
membuka aplikasi Castle Deffense ini, makan tampilan yang akan muncul pertama kali
adalah splash screen.
Kemudian setelah itu user akan masuk ke halaman menu utama. Pada menu utama
terdapat petunjuk untuk memainkan game Castle Deffence dan terdapat satu button
untuk memulai permainan. Setelah kita klik button mainkan maka user akan masuk
ke halaman game permainan Castle Deffense.
Rancangan Splash Screen
3.3.
Rancangan Menu Utama
Pada rancangan menu utama Castle Deffense, terdiri dari
gambar yang berupa ilustrasi dari suasana permainan. Kemudian di sebelas kanan
atas terdapat petunjuk permainan Castle Deffense dan di kanan bawah terdapat button
mainkan untuk masuk ke halaman permainan.
3.3.
Rancangan Halaman
Permainan
Pada rancangan halaman permainan,
terdiri dari tampilan game Castle Deffense itu sendiri.Pada bagian atas layar akan
menampilkan uang, nyawa dan score yang pemain miliki. Dan pada bagian kanan
bawah layar terdapat satu button yaitu button start untuk memulai permainan.
3.3.
Implementasi Permainan
·
Cara Bermain Castle Deffence
Buka game Castle Deffence,
kemudian yang pertama kali ketika kita membuka game tersebut akan muncul splash
screen Castle Deffence. Setelah itu pemain akan memasuki menu utama dari game Castle Deffence yang terdiri dari ilustrasi gambar, petunjuk permainan dan button
mainkan untuk masuk ke halaman permainan.
Setelah memasukin
halaman permainan, atur strategi untuk meletakkan Pasukan Mario mu di tempat yang
strategis untuk membunuh para monster. Untuk awal permainan, pemain diberikan dua
buah Pasukan Mario. Jika sudah mengatur posisi dua buah Pasukan Mario, klik button
start yang berada di kanan bawah layar untuk memulai permainan.
Pada level awal
permainan, monster yang harus dimusnakan adalah 4 ekor.
Nilai uang yang akan
pemain dapatkan jika berhasil membunuh satu monster adalah 60. Jika pemain
berhasil mengumpulkan uang sebanyak 250 maka pemain bisa menambah satu buah Pasukan Mario, sehingga jumlah Pasukan Mario yang dimilki pemain menjadi 3 dan
begitu seterusnya.
Pemain akan game over
jika jumlah monster yang lolos dari tembakan peletok gun berjumlah 10 ekor.
·
Layout Program
Tampilan Splash Screen
Tampilan Menu Utama
Tampilan Halaman Permainan
Tampilan Game Over
Coding untuk membuat game "Castle Deffense" :
Tower_defence :
/* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/6459*@* */
/* !do not delete the line above, required for linking your tweak if you upload again */
ArrayList towers;
ArrayList squares;
int fr = 0;
int dualtimer = 0;
PImage path, desa, titlepage, instructions;
int MONEY = 700;
int LIVES = 10;
int SCORE = 0;
int cols = 16;
int rows = 12;
int gridAccess [][] = new int[cols][rows];
int jmlbuaya = 4;
int buayaHealth = 100;
int maptestX, maptestY;
int placeX, placeY;
Button[] b = new Button[192];
boolean play = false;
boolean end = false;
boolean intro = false;
int timer = 0;
boolean title = true;
PFont file;
void setup () {
size(640,480);
cursor(CROSS);
rectMode(CENTER);
imageMode(CENTER);
smooth();
frameRate(30);
file = loadFont("File-24.vlw");
textFont(file);
textAlign(CENTER);
path = loadImage("basicPath1.png");
desa = loadImage("desa.png");
titlepage = loadImage("titlepage.png");
instructions = loadImage("instructions.png");
for(int h = 0; h< 192; h++) {
b[h] = new Button();
}
int u = 0; //Sets up grid ID number
for (int v = 0; v < rows; v++) {
for (int w = 0; w < cols; w++) {
gridAccess[w][v] = u;
u++;
}
}
towers = new ArrayList();
squares = new ArrayList();
}
void draw () {
maptestX = int(map(mouseX,0,640,0,16));
maptestY = int(map(mouseY,0,480,0,12));
if(title) {
dualtimer++;
if(dualtimer <= 120) {
image(titlepage,width/2,height/2);
}
else {
title = false;
intro = true;
dualtimer = 0;
}
}
if(intro) {
image(instructions,width/2,height/2+1);
fill(100);
rect(540,460,120,40); // start
//rect(500,290,120,40); // start
//rect(500,340,120,40);
//rect(500,390,120,40);
fill(255);
text("Mainkan", 540, 470);
//text("Mainkan", 500, 300);
//text("Petunjuk", 500, 350);
//text("About", 500, 400);
}
if(!title && !intro) {
dualtimer++;
pushMatrix();
translate(width/2,height/2);
image(desa,20,0);
popMatrix();
image(path,319,239);
int button_number = 0;
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 16; j++) {
b[button_number].button_display((20+(j*40)),(20+(i*40)));
button_number++;
}
}
fill(100);
rect(540,460,120,40); // start
fill(255);
if(!play || !end) {
text("START", 540, 470);
}
if (play) {
fill(#278AA8,150);
rect(540,460,120,40);
}
fill(0);
String score = "SCORE: " + " " + nf(SCORE,8);
text(score,500,30);
String money = "UANG: " + " " + nf(MONEY,4) + " rupiah";
text(money, 140, 30);
String lives = "LIVES: " + " " + nf(LIVES,2);
text(lives, 325, 30);
}
if(play) {
fr++;
if(fr == 25) {
squares.add(new Square(buayaHealth));
if(squares.size() < jmlbuaya) {
fr = 0;
}
if(squares.size() == jmlbuaya) {
fr = 30;
}
}
for(int j=0; j<squares.size(); j++) {
if(squares.size()>0)
((Square)squares.get(j)).squareDisplay();
}
if(squares.size() == 0) {
timer++;
if(timer == 120) {
fr = 0;
buayaHealth += 35;
jmlbuaya += 1;
timer = 0;
}
}
}
if(LIVES == 0) {
play = false;
end = true;
}
for(int i=0; i<towers.size(); i++) {
((Tower)towers.get(i)).tower_display();
((Tower)towers.get(i)).shoot();
}
if(end) {
for(int z = 0; z<towers.size(); z++) {
towers.remove(z);
}
lose();
}
}
void mousePressed() {
if(intro) {
if((mouseX >= 480 && mouseX <= 600) && (mouseY >= 425 && mouseY <= 465)) {
intro = false;
dualtimer = 0;
}
}
if(!play && !intro) {
if((mouseX >= 480 && mouseX <= 600) && (mouseY >= 425 && mouseY <= 465)) {
if(dualtimer > 1)
play = true;
}
}
if(!end && !intro && !title) {
if((mouseX <= 480) || (mouseX> 600) || ((mouseX >= 480 && mouseX <= 600) && mouseY >= 465) || ((mouseX >= 480 && mouseX <= 600) && mouseY <= 425)) {
if(MONEY >= 250) {
placeX = current_buttonX(maptestX,maptestY);
placeY = current_buttonY(maptestX,maptestY);
towers.add(new Tower(placeX, placeY));
MONEY -= 250;
}
}
}
}
int current_buttonX (int x, int y) {
int xpos = 0;
int buttonChoice = gridAccess[x][y];
xpos = b[buttonChoice].rectX;
return xpos;
}
int current_buttonY (int x, int y) {
int ypos = 0;
int buttonChoice = gridAccess[x][y];
ypos = b[buttonChoice].rectY;
return ypos;
}
void lose() {
fill(255);
text("GAME OVER", width/2, height/2);
text("SCORE: " + SCORE, width/2, height/2 + 40);
keyPressed();
}
void keyPressed(){
if (key == ' ') {
reset();
}
}
void reset(){
intro = true;
play = false;
end = false;
timer = 0;
fr = 0;
dualtimer = 0;
MONEY = 700;
LIVES = 10;
SCORE = 0;
jmlbuaya = 4;
buayaHealth = 100;
}
Amo :
class Amo {
PVector loc = new PVector();
Tower t;
int time = 0;
PVector center;
PVector turret;
float dirX, dirY;
PImage bullet;
Amo (float x, float y) {
loc.x = x;
loc.y = y;
turret = new PVector(loc.x, loc.y);
bullet = loadImage("bullet.png");
}
void run(float a, float b) {
dirX = a;
dirY = b;
center = new PVector(dirX, dirY);
image(bullet,loc.x,loc.y);
PVector velocity = PVector.sub(center,turret);
loc.add(new PVector(velocity.x/2, velocity.y/2));
}
}
Grid :
class Button {
int rectX = 0;
int rectY = 0;
int testX, testY;
int rectSize = 40;
color rectColor, baseColor;
color rectHighlight;
color rectRed;
color currentColor;
boolean rectOver = false;
boolean rectOn = false;
Button() {
rectHighlight = color(175,100);
rectRed = color(#278AA8,25);
baseColor = color(102);
currentColor = rectRed;
}
void button_display (int x, int y) {
rectX = x;
rectY = y;
rectColor = color(currentColor);
update(mouseX,mouseY);
testX = posX(mouseX,mouseY);
testY = posY(mouseX,mouseY);
if (rectOn) {
fill (rectRed);
}
else if (rectOver) {
fill(rectHighlight);
}
else {
fill (rectColor);
}
stroke(255,10);
rect(rectX, rectY, rectSize, rectSize);
}
void update (int x, int y) {
if (overRect(rectX, rectY, rectSize, rectSize)) {
rectOver = true;
}
else {
rectOver = false;
}
if (mousePressed && rectOver) {
rectOn = true;
}
else {
rectOn = false;
}
}
int posX (int x, int y) {
int a = 0;
if (mousePressed && rectOn) {
a = rectX;
}
return a;
}
int posY (int x, int y) {
int a = 0;
if (mousePressed && rectOn) {
a = rectY;
}
return a;
}
boolean overRect (int x, int y, int width, int height)
{
if (mouseX >= x-20 && mouseX <= x+20 && mouseY >= y-20 && mouseY <= y+20) {
return true;
}
else {
return false;
}
}
}
Squere :
class Square {
float xpos = -5;
float ypos = 100;
int speed = 2;
int health;
PImage see;
Square (int HEALTH) {
health = HEALTH;
see = loadImage("see_enemy.png");
}
void hurt() {
health -= 3;
}
void squareDisplay() {
if (xpos < 100) {
xpos += speed;
}
else if (ypos < 300 && xpos < 260) {
ypos += speed;
}
else if (xpos < 260) {
xpos += speed;
}
else if (ypos > 100 && ypos < 350 && xpos < 300) {
ypos -= speed;
}
else if (xpos < 380) {
xpos += speed;
}
else if (ypos < 380 && xpos < 450) {
ypos += speed;
}
else if (xpos < 460 && ypos > 370) {
xpos += speed;
}
else if (xpos > 450 && xpos < 470 && ypos <= 380 && ypos > 220) {
ypos -= speed;
}
else
xpos += speed;
pushMatrix();
translate(xpos,ypos);
image(see,0,0,60,75);
popMatrix();
if(xpos > width + 25) {
LIVES -= 1;
squares.remove(this);
}
if (health < 0) {
squares.remove(this);
SCORE += (100 + int(SCORE*.07));
MONEY += 60;
}
}
}
Tower :
class Tower {
ArrayList amos;
PVector location = new PVector();
float r = 40;
float aX = r;
float aY = r;
int radius = 100;
int Tfr = 0;
int inReach = 160;
PImage towerbase, towereye;
float angle;
Tower (float x, float y) {
location.x = x;
location.y = y;
amos = new ArrayList();
towerbase = loadImage("towerbase.png");
towereye = loadImage("towereye.png");
}
void tower_display() {
for (int i=0; i < squares.size(); i++) {
if(dist(((Square)squares.get(0)).xpos, ((Square)squares.get(0)).ypos,location.x,location.y) < inReach) {
angle = atan2((((Square)squares.get(0)).ypos)-location.y, (((Square)squares.get(0)).xpos)-location.x);
aX = (r * cos(angle)) + location.x;
aY = (r * sin(angle)) + location.y;
}
}
image(towerbase,location.x,location.y);
pushMatrix();
translate(location.x,location.y+1);
rotate(angle+PI-PI/13);
image(towereye,0,0);
popMatrix();
}
void shoot() {
if(squares.size()>0) {
if(dist(((Square)squares.get(0)).xpos, ((Square)squares.get(0)).ypos,location.x,location.y) < inReach) {
Tfr++;
if(Tfr == 5){
amos.add(new Amo(location.x,location.y));
Tfr = 0;
}
}
for(int k=0; k<amos.size(); k++) {
image(towerbase,location.x,location.y);
((Amo)amos.get(k)).run(aX, aY);
pushMatrix();
translate(location.x,location.y+1);
rotate(angle+PI-PI/13);
image(towereye,0,0);
popMatrix();
if(dist(((Square)squares.get(0)).xpos, ((Square)squares.get(0)).ypos, ((Amo)amos.get(k)).loc.x, ((Amo)amos.get(k)).loc.y) < 25) {
amos.remove(k);
((Square)squares.get(0)).hurt();
}
else if(((Amo)amos.get(k)).loc.x > width || ((Amo)amos.get(k)).loc.x < 0 || ((Amo)amos.get(k)).loc.y > height || ((Amo)amos.get(k)).loc.y < 0) {
amos.remove(k);
}
}
}
}
}
Selanjunya untuk melihat game Castle Deffense ini dapat diakses pada link berikut ini :