Membuat Game Racing Sederhana Dengan C++ dan Libsigil
Alat dan Bahan
- Visual Studio
- Libsigil (download disini)
- Gambar objek Mobil, Truk, Coin dan Jalan (pastikan dalam format png dan letakan pada working folder project kalian, kalau saya pribadi saya buatkan folder dengan nama data pada working directory)
- Sound untuk suara mobil tabrakan dan background music (letakan pada working directory).
Isi dari folder data
Step 1. Cara Pasang Libsigil pada Visual Studio
1. Pertama kalian buka Visual Studio
2. Buat Project baru misalkan "Need For Speed 2018" wkwkw
3. Setelah itu Pilih menu Debug dan "Need For Speed 2018 Property"
4. Pilih pada C/C++ dan pilih General, lalu di sebelah kanan akan ada beberapa pilihan lalu pada Additional Include Directories kalian ubah path nya dan arahkan ke folder Include pada LibSigil (Ekstrak dulu LibSigil)
Memasang Include Directories
5.
6. Setelah itu kita akan memasang Library Sigilnya, caranya yaitu Klik menu Linker disebelah kiri.
7. Setingan terakhir yaitu menambahkan sigil.lib ke program. Caranya yaitu masih di menu Linker tapi pilih Input dibawah General lalu di Additional Depedencies edit dan ketikan sigil.lib setelah itu Apply dan Ok. Akhirnya selesai juga seting External Librarynya, Oke kita lanjut ke pembuatan program.
Step 2. Membuat Program
Pada project kali ini kita akan membuat 6 file header dan 5 file cpp yang terdiri dari
1. car.h (untuk pendefinisian objek mobil dan merupakan turunan dari object.h)
2. truck.h (untuk pendefinisian objek truk dan merupakan turunan dari objek.h)
3. object.h (sebagai base class yang datanya diwariskan ke car.h dan truck.h)
4. misc.h (sebagai objek tambahan berupa pepohonan,coin, dan bahan bakar)
5. global.h (sebagai tempat pendefinisian texture pada game)
6. game.h (sebagai fungsi untuk memanggil game start, run dan end)
Lalu untuk file cpp nya terdiri dari
1. car.cpp (berisi konfigurasi untuk objek mobil)
2. truck.cpp (berisi konfigurasi untuk truk)
3. misc.cpp (berisi konfigurasi untuk objek tambahan)
4. game.cpp (berisi tempat semua objek objek dalam game disatukan)
5. main.cpp (fungsi main yang menjalankan state game)
Proses Coding
Pada Visual Studio bagian kanan klik kanan pada Header Files lalu add new item dan buat header file dengan nama object.h. File object.h ini digunakan untuk class induk untuk mobil dan truk. Ketikan kode seperti dibawah
Silahkan di sedot codingannya mumpung lagi baik:)
//---------Object.h-------------
#ifndef OBJECT
#define OBJECT
class object
{
protected:
double posX;
double posY;
double velX;
double velY;
public:
double getX() { return posX;}
double getY() { return posY;}
virtual void draw()= 0;
virtual void update()=0;
virtual void loadTexture() = 0;
};
#endif
Kode untuk file car.h, File ini berfungsi untuk membuat definisi dari objek mobil. Masukan kode berikut
//---------CAR.h---------------
#ifndef CAR
#define CAR
#include "object.h"
class Car: public object
{
private:
int texture;
public:
Car(double px,double py);
void draw();
void update();
void control(double cx);
void loadTexture();
};
#endif
Kode untuk truck.h , Berfungsi untuk pendefinisian objek truck. Masukan kode
//------------TRUCK.h------------
#ifndef GLOBAL
#define GLOBAL
const double SCR_W =480;
const double SCR_H =640;
//texture
const char TEX_CAR[]= "data\\car_red.png";
const char TEX_CAR2[]= "data\\car_blue.png";
const char TEX_TRUCK[]= "data\\truck_1.png";
const char TEX_ROAD[]= "data\\road.png";
const char TEX_TREE[]= "data\\tree.png";
const char TEX_COINS[]= "data\\coins.png";
const char TEX_GASOLINE[]= "data\\gasoline.png";
const char TEX_CAR_PURPLE[]= "data\\carpurple.png";
//font
const char FNT_STYLE[]= "data\\whitrabt.ttf";
//sfx
const char SFX_MUSIC[]= "data\\music.wav";
const char SFX_CRASH[]= "data\\crash.wav";
const char SFX_COINS[]= "data\\coins.wav";
#endif
Kode untuk misc.h File ini berisikan beberapa tambahan objek seperti pohon, coin, dan gasoline. Masukan kode
//------------MISC.h------------
#ifndef MISC
#define MISC
#include "object.h"
class misc:public object
{
private:
double misc_spd;
int MiscTexCoins;
int MiscTex;
int MiscTexGasoline;
public:
misc(double x,double y,double v);
void draw();
void drawcoins();
void drawgasoline();
void update();
void updatecoins();
void updategasoline();
void reset();
void resetCoins();
void resetGasoline();
void loadTexture()override;
void loadTextureCoins();
void loadTextureGasoline();
void setMiscSpd(double s);
};
#endif
Kode untuk global.h File ini berisikan pendefinisian beberapa texture pada game. Masukan kode
//------------GLOBAL.h------------
#ifndef GLOBAL
#define GLOBAL
const double SCR_W =480;
const double SCR_H =640;
//texture
const char TEX_CAR[]= "data\\car_red.png";
const char TEX_CAR2[]= "data\\car_blue.png";
const char TEX_TRUCK[]= "data\\truck_1.png";
const char TEX_ROAD[]= "data\\road.png";
const char TEX_TREE[]= "data\\tree.png";
const char TEX_COINS[]= "data\\coins.png";
const char TEX_GASOLINE[]= "data\\gasoline.png";
const char TEX_CAR_PURPLE[]= "data\\carpurple.png";
//font
const char FNT_STYLE[]= "data\\whitrabt.ttf";
//sfx
const char SFX_MUSIC[]= "data\\music.wav";
const char SFX_CRASH[]= "data\\crash.wav";
const char SFX_COINS[]= "data\\coins.wav";
#endif
Kode untuk game.h File ini berisikan fungsi pemanggilan namespace pada game.cpp ke main.cpp. Masukan kode
//------------GAME.h------------
#ifndef OGAME
#define OGAME
namespace game
{
void init();
void run();
void end();
}
#endif
Kode untuk game.cpp File ini berisikan konfigurasi untuk objek mobil. Masukan kode
//------------CAR.cpp------------
#include "car.h"
#include "object.h"
#include "sl.h"
#include "global.h"
Car::Car(double px,double py)
{
posX=px;
posY=py;
}
void Car::loadTexture()
{
texture = slLoadTexture(TEX_CAR);
}
void Car::draw()
{
slSprite(texture,posX,posY,50,85);
}
void Car::update()
{
posX+=velX;
if(posX-23 <=30 || posX+20 >=360)
velX*=-0.5;
}
void Car::control(double cx)
{
velX+=cx;
}
Kode untuk truck.cpp File ini berisikan konfigurasi objek truk. Masukan kode
//------------TRUCK.cpp------------
#include "object.h"
#include "truck.h"
#include "global.h"
#include <sl.h>
#include <cstdlib>
truck::truck(double px,double py,double vx)
{
posX=px;
posY=py;
velX=vx;
}
void truck::loadTexture()
{
texture = slLoadTexture(TEX_TRUCK);
}
void truck::draw()
{
slSprite(texture,posX,posY,50,85);
}
void truck::update()
{
posY+=truck_spd;
if(posY <= -40)
{
reset();
truck_spd-=0.2;
}
}
//fungsi untuk reset posisi truk secara random
void truck::reset()
{
int arr[]={66,132,200,266};
int random;
random=rand() % 4 ;
posY=700;
posX=arr[random];
}
void truck::setTruckSpd(double s)
{
truck_spd=s;
}
- Kode untuk misc.cpp File ini berisikan konfigurasi objek tambahan seperti pohon,coin dan gasoline. Masukan kode
//------------MISC.cpp------------
#include "misc.h"
#include <sl.h>
#include "global.h"
#include <cstdlib>
misc::misc(double x,double y,double v)
{
posX=x;
posY=y;
velY=v;
};
void misc::loadTexture()
{
MiscTex = slLoadTexture(TEX_TREE);
}
void misc::loadTextureCoins()
{
MiscTexCoins=slLoadTexture(TEX_COINS);
}
void misc::loadTextureGasoline()
{
MiscTexGasoline=slLoadTexture(TEX_GASOLINE);
}
void misc::draw()
{
slSprite(MiscTex,posX,posY,100,100);
}
void misc::drawcoins()
{
slSprite(MiscTexCoins,posX,posY,40,40);
}
void misc::drawgasoline()
{
slSprite(MiscTexGasoline,posX,posY,40,40);
}
void misc::update()
{
posY+=misc_spd;
if(posY <= -40)
{
reset();
}
}
void misc::updatecoins()
{
posY+=misc_spd;
if(posY <= -40)
{
resetCoins();
}
}
void misc::updategasoline()
{
posY+=misc_spd;
if(posY <= -40)
{
resetGasoline();
}
}
void misc::setMiscSpd(double s)
{
misc_spd=s;
}
void misc::reset()
{
posY=700;
int arr[]={365,30};
int ran=rand() % 2 ;
posX=arr[ran];
}
void misc::resetCoins()
{
int arr[]={100,132,200,245};
int ran=rand() % 4 ;
posY=2000;
posX=arr[ran];
}
void misc::resetGasoline()
{
int arr[]={100,132,200,245};
int ran=rand() % 4 ;
posY=3000;
posX=arr[ran];
}
- Kode untuk game.cpp File ini berisikan semua objek yang telah kita buat dan akan digabungkan menjadi 1. Mohon tetap tenang dan jangan pusing atau panik wkwkwk. Masukan kode
//------------GAME.cpp------------
#include "car.h"
#include "truck.h"
#include "global.h"
#include "misc.h"
#include <sl.h>
#include <iostream>
#include <string>
#include <cmath>
#include <windows.h>
//====================================//PEMBUATAN OBJEK\\===============================
Car car(200,100); //car
truck vehicle(200,400,2); //vehcile
truck vehicle2(250,600,2.5); //vehicle 2
misc tree1(365,700,1); //tree 1
misc tree2(365,900,1); //tree 2
misc tree3(365,1100,1); //tree 3
misc coins(66,750,2); //coins
misc gasoline(100,2500,2); //gasoline
//=================================================================================
//state game
enum GameState:int {Start, CarSelect,Play, Pause, GameOver};
GameState state = GameState::Start;
int road;
int font;
int sfxmusic;
int sfxcrash;
int sfxcoins;
int IcoCoin;
int IcoGasoline;
std::string player;
//score
int score=0;
int count=0;
int hiscore = 0;
int fuel=20;
//prototype
void info();
void key();
bool isCollide(object* e1, object* e2,const double h);
namespace game
{
void init()
{
//set name player
std::cout << " Your nickname: ";
std::getline(std::cin, player);
if (player == "")
player = "Antboy";
//create windows
std::cout << " creating windows...\n";
slWindow(480, 640, "Not For Speed 2018 v1.0", false);
slSetBackColor(0, 0.4, 0.2);
//load texture & font
std::cout<<" loading texture...\n";
car.loadTexture();
vehicle.loadTexture();
vehicle2.loadTexture();
tree1.loadTexture();
tree2.loadTexture();
tree3.loadTexture();
coins.loadTextureCoins();
gasoline.loadTextureGasoline();
road=slLoadTexture(TEX_ROAD);
font=slLoadFont(FNT_STYLE);
IcoCoin=slLoadTexture(TEX_COINS);
IcoGasoline=slLoadTexture(TEX_GASOLINE);
slSetFont(font,20);
//load audio
std::cout<<" loading audio...\n";
sfxmusic=slLoadWAV(SFX_MUSIC);
sfxcrash=slLoadWAV(SFX_CRASH);
sfxcoins=slLoadWAV(SFX_COINS);
//play game music
slSoundLoop(sfxmusic);
//set object speed
vehicle.setTruckSpd(-3);
vehicle2.setTruckSpd(-2);
tree1.setMiscSpd(-1);
tree2.setMiscSpd(-1);
tree3.setMiscSpd(-1);
coins.setMiscSpd(-4);
gasoline.setMiscSpd(-6);
}
void run()
{
std::cout << " Game: Run\n";
while (!slShouldClose())
{
//draw road texrure
slSprite(road,SCR_W/2,SCR_H/2,SCR_W,SCR_H);
//draw car & vehicles texture
car.draw();
vehicle.draw();
vehicle2.draw();
//draw miscellaneous
tree1.draw();
tree2.draw();
tree3.draw();
coins.drawcoins();
gasoline.drawgasoline();
//draw info & key
info();
key();
//state play
if(state ==GameState::Play)
{
//update car & vehicle
car.update();
vehicle.update();
vehicle2.update();
//update miscellaneous
tree1.update();
tree2.update();
tree3.update();
coins.updatecoins();
gasoline.updatecoins();
//penghitung score
count++;
if(count==100)
{
score++;
count=0;
}
if(count==30)
{
fuel--;
}
//mengecek apakah 2 objek bertabrakan
if (isCollide(&car, &vehicle,50.0))
{
if(score>=hiscore)
{
hiscore=score;
}
slSoundPlay(sfxcrash);
state = GameState::GameOver;
std::cout<<" *Game Over!\n";
}
if (isCollide(&car, &vehicle2,50.0))
{
if(score>=hiscore)
{
hiscore=score;
}
slSoundPlay(sfxcrash);
state = GameState::GameOver;
std::cout<<" *Game Over!\n";
}
if (isCollide(&car, &coins,40.0))
{
score+=10;
coins.resetCoins();
slSoundPlay(sfxcoins);
}
if (isCollide(&car, &gasoline,40.0))
{
fuel+=5;
gasoline.resetGasoline();
slSoundPlay(sfxcoins);
}
if(fuel==0)
{
state = GameState::GameOver;
}
}
slRender();
}
}
void end()
{
std::cout<<" Game End\n";
}
}
void key()
{
if (state == GameState::Start)
{
if (slGetKey(SL_KEY_ENTER))
state = GameState::Play;
}
else if (state==GameState::CarSelect)
{
}
else if (state == GameState::Play)
{
if(slGetKey(SL_KEY_RIGHT))
car.control(0.2);
if(slGetKey(SL_KEY_LEFT))
car.control(-0.2);
if (slGetKey('P'))
state = GameState::Pause;
}
else if (state == GameState::Pause)
{
// resume:
if (slGetKey('R'))
{
state = GameState::Play;
}
}
else if (state == GameState::GameOver)
{
// replay:
if (slGetKey('R'))
{
//reset all object
score=0;
fuel=20;
state = GameState::Play;
vehicle.reset();
vehicle.setTruckSpd(-1.5);
vehicle2.reset();
vehicle2.setTruckSpd(-2);
coins.resetCoins();
gasoline.resetGasoline();
}
}
}
void info()
{
slSetFontSize(20);
slSetTextAlign(SL_ALIGN_CENTER);
slText(SCR_W-50,SCR_H-50, player.c_str());
slSetFontSize(16);
slSetTextAlign(SL_ALIGN_CENTER);
slText(SCR_W-50, SCR_H - 100, "score");
slText(SCR_W-50, SCR_H - 120, std::to_string(score).c_str());
slText(SCR_W-50, SCR_H - 150, "hiscore");
slText(SCR_W-50, SCR_H - 170, std::to_string(hiscore).c_str());
slText(SCR_W-50, SCR_H - 210, "FUEL");
slText(SCR_W-50, SCR_H - 230, std::to_string(fuel).c_str());
if (state == GameState::Start)
{
// menampilkan instruksi:
slSetForeColor(0.0, 0.0, 0.0, 0.7);
slRectangleFill(SCR_W / 2.0, SCR_H / 2.0, SCR_W, SCR_H);
slSetFontSize(16);
slSetTextAlign(SL_ALIGN_CENTER);
slSetForeColor(1.0, 1.0, 1.0, 1.0);
slText(SCR_W / 2, 480, "Drive the Car so as not to crash");
slText(SCR_W / 2, 460, "using LEFT or RIGHT key.");
slSprite(IcoCoin,120,405,40,40);
slSprite(IcoGasoline,120,350,30,40);
slText(SCR_W / 2+25, 400, "Pick Coins for Extra Score");
slText(SCR_W / 2+35, 350, "Pick Gasoline for Extra Fuel");
slText(SCR_W / 2, 256, "Press ENTER to Start");
}
else if (state == GameState::GameOver)
{
// menampilkan Game Over dan perolehan score:
slSetForeColor(0.0, 0.0, 0.0, 0.7);
slSetFontSize(40);
slSetTextAlign(SL_ALIGN_CENTER);
slText(SCR_W / 2.0, SCR_H / 2.0, "Game Over");
slSetForeColor(1.0, 1.0, 1.0, 1.0);
slSetFontSize(16);
slText(SCR_W / 2.0 - 10, SCR_H / 2.0 - 25, "Your score:");
slText(SCR_W / 2.0 + 50, SCR_H / 2.0 - 25, std::to_string(score).c_str());
slText(SCR_W / 2.0, SCR_H / 2.0 - 60, "Press 'R' to Replay");
}
else if (state == GameState::Pause)
{
// menampilkan informasi instruksi untuk resume game:
slSetForeColor(1.0, 1.0, 1.0, 1.0);
slSetFontSize(16);
slSetTextAlign(SL_ALIGN_CENTER);
slText(SCR_W / 2.0, SCR_H / 2.0, "Press R to Resume");
}
else if (state == GameState::Play)
{
// menampilkan informasi instruksi pause game:
slSetForeColor(1.0, 1.0, 1.0, 1.0);
slSetFontSize(16);
slSetTextAlign(SL_ALIGN_RIGHT);
slText(SCR_W - 15, SCR_H - 25, "Press P to Pause");
}
}
//fungsi untuk mengecek tabrakan 2 objek
bool isCollide(object* e1, object* e2,const double h)
{
return (std::hypot(e1->getX() - e2->getX(), e1->getY() - e2->getY()) <= h);
}
- Terakhir gan, Kode untuk main.cpp File ini cuma berisikan namespace dari game.h dan akan memnaggil fungsi start, run dan end pada game.cpp . Masukan kode
//------------MAIN.cpp------------
#include "game.h"
int main()
{
game::init();
game::run();
game::end();
return 0;
}
Komentar
Posting Komentar