Reading From Keyboard

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
eysidisi
Posts: 3
Joined: December 26th, 2017, 11:01 am

Reading From Keyboard

Post by eysidisi » December 26th, 2017, 12:31 pm

Hello all,

First of all since it's my first post I'd like to thank Chili for all good stuff. Here is my question:

I'm trying to make a platform game using Chili's framework. And when "control" key is pressed my character needs to fire a missile and when control key is pressed for second time it needs to fire another missile and it's the limit. The problem is when I hit control key it sends two missiles simultaneously. I tried to add sleep function after reading the key and It did work but It causes my whole game to freeze for some time. Is there a way to read a key for once or can I read releasing a key instead of pressing? I'm giving the code snippet of the related part and uploading my solution file.(it's in the Player.cpp file) Thank you in advance.

Code: Select all

// ----------------------------Firing Missile------------------------------------
	if (kbd.KeyIsPressed(VK_CONTROL) && missileCounter<2)
	{

		if (isMissile1Fired==false)
		{
			mis1 = new Missile(x + Player::xDimension, y + Player::yDimension / 2,isLookingRight);
			isMissile1Fired = true; 
			missileCounter += 1;
		}

		else if (isMissile2Fired == false)
		{
			mis2 = new Missile(x + Player::xDimension, y + Player::yDimension / 2,isLookingRight);
			isMissile2Fired = true;
			missileCounter += 1;

		}
	}
Attachments
eysidisi_game.rar
(242.22 KiB) Downloaded 132 times

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Reading From Keyboard

Post by MrGodin » December 26th, 2017, 6:37 pm

KeyIsPressed is getting logged every frame so it is firing two objects one frame apart. You can try this
Keyboard::Event ev = kbd.ReadKey();
if (ev.IsRelease())
{
int f = 0;
};
but that is for any key
i used to do something like this

Code: Select all

static bool hasFired = false;
// only fire when hasFired is false
if (kbd.KeyIsPressed(VK_CONTROL) && !hasFired)
{
   hasFired = true;
}
// this will become false again when the key is released
// enabling you to fire again
hasFired = kbd.KeyIsPressed(VK_CONTROL);
You can do a timer between shots too i suppose
I'm sure there are other ways, i just can't think of them right now
Peace
Curiosity killed the cat, satisfaction brought him back

User avatar
Yumtard
Posts: 575
Joined: January 19th, 2017, 10:28 pm
Location: Idiot from northern Europe

Re: Reading From Keyboard

Post by Yumtard » December 26th, 2017, 9:20 pm

Yeah use events and check IsPress()
then have something like ammuntion.

Code: Select all

while( !wnd.kbd.KeyIsEmpty() )
 {
  	const Keyboard::Event e = wnd.kbd.ReadKey();

 	if ( e.IsPress() )
 	{
 		if ( e.GetCode() == VK_CONTROL )
		{
			missle.Fire();
 		}
}
inside Fire() you'd do something like

if (hasAmmo)
{
//insert code for launching missle
ammo--;
}


if you want the ammo to be reloaded every second or whatever you can do that inside missle.Update()

reloadTimer += detlaTime;
if (reloadTimer >= 1.0f)
{
reloadTimer = 0.0f;
ammo = 2;
}

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Reading From Keyboard

Post by MrGodin » December 26th, 2017, 9:43 pm

Yeah what Yumtard said :P
Curiosity killed the cat, satisfaction brought him back

eysidisi
Posts: 3
Joined: December 26th, 2017, 11:01 am

Re: Reading From Keyboard

Post by eysidisi » December 27th, 2017, 1:03 pm

Thanks for your replies but while I was trying to create event I encountered with errors

Code: Select all

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2662	'Keyboard::Event Keyboard::ReadKey(void)': cannot convert 'this' pointer from 'const Keyboard' to 'Keyboard &'	Engine	c:\users\ali ihsan\desktop\oyun\engine\player.cpp	341	
and

Code: Select all

Severity	Code	Description	Project	File	Line	Suppression State	Detail Description
Error (active)		the object has type qualifiers that are not compatible with the member function "Keyboard::ReadKey"	Engine	c:\Users\Ali ihsan\Desktop\oyun\Engine\Player.cpp	341		            object type is: const Keyboard
. I'm kind of a newbie and couldn't solve it instead I came up with this solution using the ideas you gave

Code: Select all

if ( missileCounter<2 &&isFiringEnabled)
	{

		if (isMissile1Fired==false && kbd.KeyIsPressed(VK_CONTROL))
		{
			mis1 = new Missile(x + Player::xDimension, y + Player::yDimension / 2,isLookingRight);
			isMissile1Fired = true; 
			missileCounter += 1;
		}


		else if (isMissile2Fired == false && kbd.KeyIsPressed(VK_CONTROL))
		{
			mis2 = new Missile(x + Player::xDimension, y + Player::yDimension / 2,isLookingRight);
			isMissile2Fired = true;
			missileCounter += 1;

		}
		

	}

	if (kbd.KeyIsPressed(VK_CONTROL))
		isFiringEnabled = false;
	else
		isFiringEnabled = true;
Thanks for your help!

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: Reading From Keyboard

Post by chili » December 27th, 2017, 2:18 pm

The readkey function is not const, so you need to pass your kbd object around as Keyboard&, not const Keyboard&.

Think of it, reading events out of the keyboard's event queue modifies the object, so you need non-const ref.
Chili

User avatar
Yumtard
Posts: 575
Joined: January 19th, 2017, 10:28 pm
Location: Idiot from northern Europe

Re: Reading From Keyboard

Post by Yumtard » December 27th, 2017, 6:06 pm

It's great that you figured out another way to solve your problem. That's a big part of programming.

The issue I have with that type of code is that it quickly becomes confusing. And what if later you decide that you want 5 missles instead of 2?
Now you need
mis3
mis4
mis5
isMissile3Fired
isMissile4Fired
isMissile5Fired

and three more else if checks.

If you were to do something similar to my example all you'd need to change is from const int ammo = 2; to const int ammo = 5;

eysidisi
Posts: 3
Joined: December 26th, 2017, 11:01 am

Re: Reading From Keyboard

Post by eysidisi » December 28th, 2017, 12:21 pm

And what if later you decide that you want 5 missles instead of 2?
I noticed that problem and now I'm using arrays. So now the code is

Code: Select all

for( int n = 0; n < numberOfMissiles; n++ )
{
	if ( isMissileFired[ n ] == false && kbd.KeyIsPressed( VK_CONTROL ) && isFiringEnabled )
	{
		mis[n] = new Missile(x + Player::xDimension, y + Player::yDimension / 2, isLookingRight);
			
		isMissileFired[n] = true; 
			
		missileCounter += 1;
			
		if (kbd.KeyIsPressed(VK_CONTROL))
			isFiringEnabled = false;
		else
			isFiringEnabled = true;
	}
}

I really appreciate your help. This project means a lot to me. Not because I'm planning to sell it on steam or anything like that. I'm doing this to learn c++ as good as I can. I did quit my job last month to work as a software engineer(hopefully in computer games business) and you know people want to see how much you know about a programming language before hiring you if you don't have any professional experience(like me) at this discipline. I'm planning to use this project to show my expertise.
I got one more question. I'm planning to write code for a computer controlled oppenent. But I don't know where to start. Is there a tutorial video from chili for that? And can you give me any suggestions about that? I'm uploading a sketch that describes my game.(sorry for my shitty drawing) That would be great if you could have a look at that and give me your opinion.
Attachments
Game.jpg
(40.28 KiB) Not downloaded yet

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Reading From Keyboard

Post by MrGodin » December 28th, 2017, 3:51 pm

There are short cuts you can do for things like this

Code: Select all


if( kbd.KeyIsPressed( VK_CONTROL ) )
	isFiringEnabled = false;
else
	isFiringEnabled = true;

// instead just go
isFireEnabled = !kbd.KeyIsPressed(VK_CONTROL);

// where the ! = not, or the opposite of the result of  kbd.KeyIsPressed(VK_CONTROL)
As for AI, thats a tough on to figure out. Start simple by moving the computer agent towards the player. Chilis TWIN project has an example of this where the "poo" follows the player. start with small things like that.
Curiosity killed the cat, satisfaction brought him back

Post Reply