0% found this document useful (0 votes)
147 views12 pages

FPS Game

This document contains a C++ OpenGL program that implements a simple first-person shooter game using GLUT. The game features a camera that can move and shoot bullets at randomly placed targets, with a scoring system based on hits. Key functionalities include target initialization, bullet firing, movement controls, and rendering of the game scene with a crosshair and score display.

Uploaded by

mersha abdisa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
147 views12 pages

FPS Game

This document contains a C++ OpenGL program that implements a simple first-person shooter game using GLUT. The game features a camera that can move and shoot bullets at randomly placed targets, with a scoring system based on hits. Key functionalities include target initialization, bullet firing, movement controls, and rendering of the game scene with a crosshair and score display.

Uploaded by

mersha abdisa
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

#include <GL/glut.

h>

#include <cmath>

#include <vector>

#include <cstdlib>

#include <ctime>

// Camera position and orientation

float cameraX = 0.0f, cameraY = 1.0f, cameraZ = 5.0f;

float lookX = 0.0f, lookY = 0.0f, lookZ = -1.0f;

float angleX = 0.0f, angleY = 0.0f;

// Movement variables

bool keyStates[256] = {false};

float moveSpeed = 0.1f;

float mouseSensitivity = 0.2f;

// Target structure

struct Target {

float x, y, z;

bool active;

};

std::vector<Target> targets;

// Bullet structure

struct Bullet {

float x, y, z;

float dx, dy, dz;

bool active;

};
std::vector<Bullet> bullets;

// Score

int score = 0;

void initTargets() {

srand(time(0));

for (int i = 0; i < 10; ++i) {

Target t;

t.x = (rand() % 20) - 10;

t.y = (rand() % 4) + 0.5f;

t.z = (rand() % 20) - 20;

t.active = true;

targets.push_back(t);

void drawTarget(float x, float y, float z) {

glPushMatrix();

glTranslatef(x, y, z);

glColor3f(1.0f, 0.0f, 0.0f); // Red target

// Draw a simple cube as target

glutSolidCube(0.5f);

glPopMatrix();

void drawBullet(float x, float y, float z) {


glPushMatrix();

glTranslatef(x, y, z);

glColor3f(1.0f, 1.0f, 0.0f); // Yellow bullet

// Draw a small sphere as bullet

glutSolidSphere(0.1f, 10, 10);

glPopMatrix();

void drawCrosshair() {

glDisable(GL_DEPTH_TEST);

glMatrixMode(GL_PROJECTION);

glPushMatrix();

glLoadIdentity();

gluOrtho2D(0, 100, 0, 100);

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glLoadIdentity();

glColor3f(1.0f, 1.0f, 1.0f);

glBegin(GL_LINES);

// Horizontal line

glVertex2f(48, 50);

glVertex2f(52, 50);

// Vertical line

glVertex2f(50, 48);

glVertex2f(50, 52);
glEnd();

glPopMatrix();

glMatrixMode(GL_PROJECTION);

glPopMatrix();

glMatrixMode(GL_MODELVIEW);

glEnable(GL_DEPTH_TEST);

void fireBullet() {

Bullet b;

b.x = cameraX;

b.y = cameraY;

b.z = cameraZ;

// Direction vector is the camera's look direction

b.dx = lookX * 0.5f;

b.dy = lookY * 0.5f;

b.dz = lookZ * 0.5f;

b.active = true;

bullets.push_back(b);

void updateBullets() {

for (size_t i = 0; i < bullets.size(); ) {

if (!bullets[i].active) {

bullets.erase(bullets.begin() + i);

continue;
}

bullets[i].x += bullets[i].dx;

bullets[i].y += bullets[i].dy;

bullets[i].z += bullets[i].dz;

// Check if bullet hits any target

for (size_t j = 0; j < targets.size(); ++j) {

if (targets[j].active &&

abs(bullets[i].x - targets[j].x) < 0.5f &&

abs(bullets[i].y - targets[j].y) < 0.5f &&

abs(bullets[i].z - targets[j].z) < 0.5f) {

targets[j].active = false;

bullets[i].active = false;

score++;

break;

// Deactivate bullet if it goes too far

if (abs(bullets[i].x) > 50 || abs(bullets[i].y) > 50 || bullets[i].z < -50) {

bullets[i].active = false;

i++;

void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

// Set camera position and orientation

gluLookAt(cameraX, cameraY, cameraZ,

cameraX + lookX, cameraY + lookY, cameraZ + lookZ,

0.0f, 1.0f, 0.0f);

// Draw ground

glColor3f(0.5f, 0.5f, 0.5f);

glBegin(GL_QUADS);

glVertex3f(-50.0f, 0.0f, -50.0f);

glVertex3f(-50.0f, 0.0f, 50.0f);

glVertex3f( 50.0f, 0.0f, 50.0f);

glVertex3f( 50.0f, 0.0f, -50.0f);

glEnd();

// Draw targets

for (const Target& t : targets) {

if (t.active) {

drawTarget(t.x, t.y, t.z);

// Draw bullets

for (const Bullet& b : bullets) {

if (b.active) {

drawBullet(b.x, b.y, b.z);

}
}

// Draw crosshair

drawCrosshair();

// Display score

glDisable(GL_DEPTH_TEST);

glMatrixMode(GL_PROJECTION);

glPushMatrix();

glLoadIdentity();

gluOrtho2D(0, 100, 0, 100);

glMatrixMode(GL_MODELVIEW);

glPushMatrix();

glLoadIdentity();

glColor3f(1.0f, 1.0f, 1.0f);

glRasterPos2f(10, 90);

std::string scoreStr = "Score: " + std::to_string(score);

for (char c : scoreStr) {

glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, c);

glPopMatrix();

glMatrixMode(GL_PROJECTION);

glPopMatrix();

glMatrixMode(GL_MODELVIEW);

glEnable(GL_DEPTH_TEST);
glutSwapBuffers();

void reshape(int w, int h) {

if (h == 0) h = 1;

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(60.0f, (float)w / (float)h, 0.1f, 100.0f);

glMatrixMode(GL_MODELVIEW);

void keyboard(unsigned char key, int x, int y) {

keyStates[key] = true;

if (key == 27) { // ESC key

exit(0);

void keyboardUp(unsigned char key, int x, int y) {

keyStates[key] = false;

void mouse(int x, int y) {

static int centerX = 400, centerY = 300;


int deltaX = x - centerX;

int deltaY = y - centerY;

angleY += deltaX * mouseSensitivity;

angleX += deltaY * mouseSensitivity;

// Clamp vertical rotation

if (angleX > 89.0f) angleX = 89.0f;

if (angleX < -89.0f) angleX = -89.0f;

// Calculate new look direction

lookX = sin(angleY * M_PI / 180.0f);

lookY = -sin(angleX * M_PI / 180.0f);

lookZ = -cos(angleY * M_PI / 180.0f) * cos(angleX * M_PI / 180.0f);

// Normalize look vector

float length = sqrt(lookX*lookX + lookY*lookY + lookZ*lookZ);

lookX /= length;

lookY /= length;

lookZ /= length;

// Reset mouse to center of screen

glutWarpPointer(centerX, centerY);

void mouseClick(int button, int state, int x, int y) {

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {

fireBullet();

}
}

void update(int value) {

// Handle movement based on key states

if (keyStates['w']) {

cameraX += lookX * moveSpeed;

cameraZ += lookZ * moveSpeed;

if (keyStates['s']) {

cameraX -= lookX * moveSpeed;

cameraZ -= lookZ * moveSpeed;

if (keyStates['a']) {

// Strafe left

cameraX -= cos(angleY * M_PI / 180.0f) * moveSpeed;

cameraZ += sin(angleY * M_PI / 180.0f) * moveSpeed;

if (keyStates['d']) {

// Strafe right

cameraX += cos(angleY * M_PI / 180.0f) * moveSpeed;

cameraZ -= sin(angleY * M_PI / 180.0f) * moveSpeed;

if (keyStates[' ']) { // Space bar

cameraY += moveSpeed;

if (keyStates['c']) {

cameraY -= moveSpeed;

}
// Keep camera above ground

if (cameraY < 0.5f) cameraY = 0.5f;

updateBullets();

glutPostRedisplay();

glutTimerFunc(16, update, 0); // ~60 FPS

int main(int argc, char** argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize(800, 600);

glutCreateWindow("Simple FPS Game");

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyboard);

glutKeyboardUpFunc(keyboardUp);

glutPassiveMotionFunc(mouse);

glutMouseFunc(mouseClick);

glutTimerFunc(0, update, 0);

// Hide cursor and capture mouse

glutSetCursor(GLUT_CURSOR_NONE);

glutWarpPointer(400, 300);

// Initialize game elements

initTargets();
// Enable depth testing

glEnable(GL_DEPTH_TEST);

glutMainLoop();

return 0;

You might also like