C++ GAME HELP!

Pages: 123

ok, here you go... its important that you fully understand what is going on in the code otherwise this help I have given you will be of no benefit.. remember that the next exercise will most likely be harder so that's why I say its important to understand what's going on.

Structure has been removed and code modified.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

#include <iostream>
#include <Windows.h>   // for gotoxy
#include <conio.h>   // for _kbhit() / _getch()
using namespace std;

#define BULLET_SPEED 70;

void gotoxy(int x, int y);

int main()
{

	// bullet variables **************************
	
	int bulletX = 0;
	int bulletY = 0;
	int timer = BULLET_SPEED;  // simple timer to slow bullet a bit
	bool alive = false;
	
	// *******************************************
	
	bool playing = true;
	char ch;

	int shipXPos = 0, shipYPos = 23;

	do
	{		

		// have i sensed a key press? - we need to do this
		// because _getch would normally wait and therefore
		// stop the updating of bullets etc.

		if (_kbhit())
		{
			// yes, what was it?
			ch = _getch();

			switch (ch)
			{
			case 'z':
				shipXPos--;
				if (shipXPos < 0) shipXPos = 0;
				break;
			case 'x':
				shipXPos++;
				if (shipXPos > 50) shipXPos = 50;
				break;
			case ' ':
				if (!alive)
				{
					// set the bullet position to
					// the ship, and set to active.
					bulletX = shipXPos + 1;
					bulletY = shipYPos;
					alive = true;  // flag it as active
				}
				break;
			}		

			system("cls");
		}

		// code to keep the bullet updated (moving) until
		// it reaches the top of the screen, then marks it
		// as not active ready for the next bullet.

		if (alive)
		{
			timer--;
			// clear last position
			if (timer == 0) {
				gotoxy(bulletX, bulletY);
				cout << " ";
				bulletY--;
				if (bulletY < 1)
					alive = false;
				else
				{
					// draw new position
					gotoxy(bulletX, bulletY);
					cout << "*";
				}
				timer = BULLET_SPEED;  // 70 seemed fine on this machine
			}
		}

		// draw the ship
		gotoxy(shipXPos, shipYPos);
		cout << " * ";
		gotoxy(shipXPos, shipYPos + 1);
		cout << "***";

	} while (playing);

	return 0;

}

// gotoxy
void gotoxy(int x, int y)
{
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

Last edited on


A modified version with an enemy ship and colliision detection. Thats me done lol, you now have the basis of a moveable player ship with a gun, and a enemy ship that can be shot at using a simple IF statement.

The rest is all up to you, have fun and take care :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

#include <iostream>
#include <Windows.h>   // for gotoxy
#include <conio.h>   // for _kbhit() / _getch()
using namespace std;

#define BULLET_SPEED 70
#define ENEMY_SPEED 150

void gotoxy(int x, int y);

int main()
{

	// bullet variables **************************
	int bulletX = 0;
	int bulletY = 0;
	int timer = BULLET_SPEED;  // simple timer to slow bullet a bit
	bool Bulletalive = false;
	
	// enemy variables   **************************
	int enemyX = 0;
	int enemyY = 1;
	int enemyTimer = ENEMY_SPEED;
	int enemyAlive = true;
	char dirHorizontal = 'r';   // r = right
	
	bool playing = true;
	char ch;

	int shipXPos = 0, shipYPos = 23;

	do
	{		
		// have i sensed a key press? - we need to do this
		// because _getch would normally wait and therefore
		// stop the updating of bullets etc.

		if (_kbhit())
		{
			// yes, what was it?
			ch = _getch();

			switch (ch)
			{
			case 'z':
				shipXPos--;
				if (shipXPos < 0) shipXPos = 0;
				break;
			case 'x':
				shipXPos++;
				if (shipXPos > 50) shipXPos = 50;
				break;
			case ' ':
				if (!Bulletalive)
				{
					// found one, set its position to
					// the ship, and set to active.
					bulletX = shipXPos + 1;
					bulletY = shipYPos;
					Bulletalive = true;  // flag it as active
				}
				break;
			}		

			system("cls");
		}

		// code to move the enemy ship
		if (enemyAlive)
		{
			enemyTimer--;
			if (enemyTimer == 0)
			{
				// clear old
				gotoxy(enemyX, enemyY);
				cout << "   ";

				switch (dirHorizontal)
				{
				case 'l':
					enemyX--;
					if (enemyX == 0)
						dirHorizontal = 'r';   // right
					break;
				case 'r':
					enemyX++;
					if (enemyX == 50)
						dirHorizontal = 'l';   // left
					break;
				}

				gotoxy(enemyX, enemyY);
				cout << "###";
				enemyTimer = ENEMY_SPEED;
			}
		}

		// code to keep the bullet updated (moving) until
		// it reaches the top of the screen, then marks it
		// as not active ready for the next bullet.

		if (Bulletalive)
		{
			timer--;
			// clear last position
			if (timer == 0) {
				gotoxy(bulletX, bulletY);
				cout << " ";
				bulletY--;
				if (bulletY < 0)
					Bulletalive = false;
				else
				{
					// draw new position
					gotoxy(bulletX, bulletY);
					cout << "*";
				}
				timer = BULLET_SPEED;  // 10 seemed fine on this machine
			}
		}

		// draw the ship
		gotoxy(shipXPos, shipYPos);
		cout << " * ";
		gotoxy(shipXPos, shipYPos + 1);
		cout << "***";

		// now for the ugly IF statement, check if I collide with the
		// enemy ship and show a message if i do.
		if (bulletX == enemyX && bulletY == enemyY && Bulletalive ||
			bulletX == enemyX + 1 && bulletY == enemyY && Bulletalive ||
			bulletX == enemyX + 2 && bulletY == enemyY && Bulletalive)
		{
			playing = false;
			gotoxy(20, 20);
			cout << "Well done you hit the enemy!";
			_getch();
		}

	} while (playing);

	return 0;

}

// gotoxy
void gotoxy(int x, int y)
{
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

@ Computergeek01

Now you have a console shooter ;-)

be it, not the way id write a shooter but its in a console like he wanted lol, id have preferred using classes but meh..

Anyway, just messing with you, take care :)

thanks a lot, actually i had used classes last time but teacher refused.

By the way thanks a lot.
i dont get this part just this:-

1
2
3
bulletX = shipXPos + 1;
bulletY = shipYPos;
Bulletalive = true


why is bulletxpos being + 1, shouldnt bulletypos +1..
and why is bullet = true in the end, shouldn't we flag it before.


and this one
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if (enemyAlive)
		{
			enemyTimer--;
			if (enemyTimer == 0)
			{
				// clear old
				gotoxy(enemyX, enemyY);
				cout << "   ";

				switch (dirHorizontal)
				{
				case 'l':
					enemyX--;
					if (enemyX == 0)
						dirHorizontal = 'r';   // right
					break;
				case 'r':
					enemyX++;
					if (enemyX == 50)
						dirHorizontal = 'l';   // left
					break;
				}

				gotoxy(enemyX, enemyY);
				cout << "###";
				enemyTimer = ENEMY_SPEED;
			}
		}

what is dirHorizontal and shouldn't enemyxpos-- go left and xpos++ right?

and could u explain me the timer?

1
2
3
4
gotoxy(shipXPos, shipYPos);
		cout << " * ";
		gotoxy(shipXPos, shipYPos + 1);
		cout << "***";

and this stuff could we have put it above the ship movement?

and in line 131 u used this ||
why u used that?

and what is this for
1
2
bulletX == enemyX + 1 && bulletY == enemyY && Bulletalive ||
			bulletX == enemyX + 2 && bulletY == enemyY && Bulletalive)


i am sorry for so many questions, its just that i am new to this. sorry :(

and thanks for all your effort :)
Last edited on

BulletX is horizontal (left/right) and bulletY is vertical (up/down) - I add 1 so that the bullet starts in the centre of the players ship (the point of the ship).

We shouldn't add 1 to bulletY here because its just the starting point for the bullet, the bullet position, i.e. subtracting 1 from it to move to the top of the screen is taken care by lines 103 - 121

We shouldn't flag it (set bulletAlive to true) before initialising the start positions otherwise the bullet will fire in some random position, i.e. code at lines 103-121 wont run until bulletAlive = true.
thanks a lot, actually i had used classes last time but teacher refused.

Classes are the be all and end all of programming, up there with pointers :) - what's your teaching thinking :D


This is the enemy update code which updates the enemys position, it checks the value in dirHorizontal to see if its a l or r (left or right so it knows which direction it needs to go) and adds or subtracts from the ships enemyX position.

It starts off moving right, when it reaches position 50, it changes dirHorizontal to l to tell it we want to move left, then it rinses and repeats.

Timer is a simple countdown delay variable, basically what happens here is the function is run continuous but each time its run it subtracts 1 from timer, when the timer variable hits 0 it will perform the update on the ship, then reset the timer back to the delay value held in ENEMY_SPEED. What this does is delay the movement code so the ship doesn't run too quick.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
		if (enemyAlive)
		{
			enemyTimer--;
			if (enemyTimer == 0)
			{
				// clear old
				gotoxy(enemyX, enemyY);
				cout << "   ";

				switch (dirHorizontal)
				{
				case 'l':
					enemyX--;
					if (enemyX == 0)
						dirHorizontal = 'r';   // right
					break;
				case 'r':
					enemyX++;
					if (enemyX == 50)
						dirHorizontal = 'l';   // left
					break;
				}

				gotoxy(enemyX, enemyY);
				cout << "###";
				enemyTimer = ENEMY_SPEED;
			}
		}


|| means OR so in a IF statement you can do things like

1
2
if(name == "Michael" || name == "John")
//.... do something 


The above would do something if the name variable contained Michael or John.

What I am doing in the next code is I am checking if the bulletX and enemyX are the same, bulletY and enemyY are the same and if they are we hit the ship with the bullet. The || statement is there because the ship is three characters wide therefore bullet would hit in 3 different x positions (hence the +1, +2)... see what I mean?

1
2
3
4
5
6
7
8
9
		if (bulletX == enemyX && bulletY == enemyY && Bulletalive ||
			bulletX == enemyX + 1 && bulletY == enemyY && Bulletalive ||
			bulletX == enemyX + 2 && bulletY == enemyY && Bulletalive)
		{
			playing = false;
			gotoxy(20, 20);
			cout << "Well done you hit the enemy!";
			_getch();
		}
Last edited on
thanks a bloody lot!
now i understand all this stuff...!!!!

Now i must show it to my teacher tommorow. She is a very demanding person..... ahh.


THANKS A LOT!

Just make sure you know exactly what's going on and have learned from it, otherwise it will be of no benefit to you, especially when the next exercise comes as it will probably be harder :)

But to be honest, with the amount of questions you fired at me it does seem like you want to learn and not simply copy it - this is a good sign!!

Take care.
thanks, i understoo the code, i always used to write if and else if statements now i will only use if and in if i will use || for many trues.
just hope my teacher accepts it.

My parents gifted me a book for my b'day last week c++ primer plus 6th edition. Is it a good book?

By the way i know you are a lot better than me at this but why do u make the input so complex, for if, like u use if and switch for input.. i am not sure if i am correct but i kind of made my own way, is this correct?
1
2
3
4
char hit = getch();
if(hit == ' '||'W'){
do something
}

is it correct?
Last edited on

Always reference the variable again after a ||

So..
1
2
if(hit == ' ' || hit == 'W')
// do something... 

When you have multiple checks its sometimes much better to use a switch statement rather than lots of IF statements, plus it makes your code more readable which is important.


take the left and right code, instead of the switch it would look like this..
1
2
3
4
5
6
7
8
9
10
11

if (dirHorizontal == 'l')
{
	// do left code
}
else
	if (dirHorizontal == 'r')
	{
		// do right code.
	}


You couldnt do the following otherwise the do something would happen if it was l or r

1
2
3
4
if (dirHorizontal == 'l' || dirHorizontal == 'r')
{
	// do something
}


Its pretty much flow control: http://www.cplusplus.com/doc/tutorial/control/

By the way, thats a good book.
Last edited on
thanks
ahhh so sorry again!
MY BLOODY TEACHER IS DEMANDING ME NOT TO USE #define!!

I WANNA KILL HER!

is there a way to change #define to a constant variable using char?

so sorry so sorry, she is sooo blooody beeped up!
that b&*#h wants everything basic!

is there a way i can convert #define to constant var?

so sorry again. :(

could you please tell me how to convert it to constant var so that i can even use it in the future?
Last edited on
#defines which are used to define a single value can be replaced by const ints.

1
2
#define BULLET_SPEED 70
#define ENEMY_SPEED 150 


1
2
const int BULLET_SPEED = 70;
const int ENEMY_SPEED = 150;


haha, your teacher is quite picky :)

No need to apologise, don't mind helping.
Last edited on
This entire thread is why I feel like I can't go back to school for this stuff. The #define preprocessor command is as simple as a macro can get, all it does is tell the compiler to do a find and replace operation at compile time. There is NOTHING complicated or confusing about this command. Then next thing we'll see is this teacher telling you not to use #include, but that you should copy and paste the contents of the header file by hand instead.
Then next thing we'll see is this teacher telling you not to use #include


That wouldn't surprise me in the slightest lol
Pages: 123