Sign in to follow this  

92 line C++ code...why does it regester 2 key hits instead of one?

This topic is 4736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

riiight... writing a pong game using only ascii symbols as sprites (48('0')=ball 220=you wall=game) anyway...i'm doing tests (did border first...then i started music and high score but decided to do the movement as a quick test seeing as it shouldn't be too hard)...anyway...i figured the entire thing out...except whenever you hit the up key it regesters as going up 2 spaces and whenever you hit the down it regesters as going down 2 spaces...how can I fix this (without saying [x is hight--0 is top] x=x-2 then x=x/2) this is the code:
#include <iostream.h>
#include <stdlib.h>
#include <windows.h>

HANDLE hInput, hOutput;

int main()
{
  char me = 220;       //me is the ASCII "sprite"
  int x = 0;           //x is your location (on the Y acess but still...we can pretend)
  int i;               //i is for counting down...
  std::cout << "\n\n\n\t\t\t#################################" << std::endl;       //introduction
  std::cout << "\t\t\t###                           ###" << std::endl;
  std::cout << "\t\t\t### PURPOSE:          TEST    ###" << std::endl;
  std::cout << "\t\t\t### PROGRAMMER:      AJAIN    ###" << std::endl;
  std::cout << "\t\t\t### DATE:         28/12/04    ###" << std::endl;
  std::cout << "\t\t\t###                           ###" << std::endl;
  std::cout << "\t\t\t#################################" << std::endl;
  std::cout << "\t\t\t###         SUMMARY           ###" << std::endl;
  std::cout << "\t\t\t###  <|>  <|>  <|>  <|>  <|>  ###" << std::endl;
  std::cout << "\t\t\t###     This test was made    ###" << std::endl;
  std::cout << "\t\t\t###      in order to test     ###" << std::endl;
  std::cout << "\t\t\t###  movement for a pong game ###" << std::endl;
  std::cout << "\t\t\t###      which is yet in      ###" << std::endl;
  std::cout << "\t\t\t###        development.       ###" << std::endl;
  std::cout << "\t\t\t#################################\n\n\n\n" << std::endl << std::endl;   //end intro
  system("PAUSE");
  system("CLS");
  hInput = GetStdHandle(STD_INPUT_HANDLE);          //initiate keys
  hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  SetConsoleMode(hInput, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
  INPUT_RECORD InputRecord;                                       //end initiation
  while(1) {                                                      //game loop
    DWORD Events=0;                                               //more initiation...
    ReadConsoleInput(hInput, &InputRecord, 1, &Events);           //and more...
    system("CLS");                                                //right before every key press the screen clears
    if(InputRecord.EventType == KEY_EVENT) {                      //if something happens to a key (namely: it gets pressed)...
      if(InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_UP) {   //if it was the up key...
        FlushConsoleInputBuffer(hInput);                          //clear the input so it won't fry...
        if (x == 0) {                                             //if it was already at the top (0)...
          i = 0;                                                  //you go down 10 "returns"...count up
          while (i != 10) {                                       //while i isn't 10...
            std::cout << i << std::endl;                          //you make 1 return and print the number...
            i = i + 1;                                            //then make i go down by 1...check off that return, in essence...
          }                                                       //by the time it ends we are at the bottom...
          std::cout << "\a WHOOPS!  One too far!" << std::endl;   //alert the person with a beep and notice...
        }
        if (x != 0) {                                             //if its all hunky dory...
          x = x - 1;                                              //add 1 more line up...this is the up arrow key!
          i = 0;                                                  //count up to 10...
          while (i != 10) {                                       //while i isn't 10...
            std::cout << i;                                       //print i
            if (x == i) {                                         //if x is i...
              std::cout << " " << me << std::endl;                //print a space (after the number) then the ascii "sprite" then end line
            }
            if (x != i) {                                         //if x isn't i...
              std::cout << std::endl;                             //just put a return...
            }
            i = i + 1;                                            //be sure you're counting up...
          }
        }
      }                                                           //thats it for the up arrow key...
      if(InputRecord.Event.KeyEvent.wVirtualKeyCode == VK_DOWN) { //if the down key was struck...
        FlushConsoleInputBuffer(hInput);                          //clear...
        if (x == 10) {                                            //if x is as far as it can go down...
          i = 0;                                                  //count up...
            while (i != 10) {                                     //while i isn't 10...
              std::cout << i << std::endl;                        //print i...
              i = i + 1;                                          //go on to next value...
            }
          std::cout << "\a WHOOPS!  One too far!" << std::endl;   //alert the person with a beep and notice...
        }
        if (x != 10) {                                            //if x isn't as far as it can go...
          x = x + 1;                                              //go down one more space...
          i = 0;                                                  //count from bottom...
          while (i != 10) {                                       //while i isn't at 10...
            std::cout << i;                                       //print i...
            if (x == i) {                                         //if x is equal to i...
              std::cout << " " << me << std::endl;                //print a space, the ascii "sprite", and an enter...
            }
            if (x != i) {                                         //if x isn't i though...
              std::cout << std::endl;                             //only do a return
            }
            i = i + 1;
          }
        }
      }
    }
  }                                                               //end game loop...
  system("PAUSE");
  return 0;
}
thanks in advance... -Ajain

Share this post


Link to post
Share on other sites
I'm not familiar with the API you're using there, but what might be happening is that a key "hit" actually causes two events to be triggered: one for the key being pressed and the other for the key being released. Have a look in your API docs for a way to differentiate between a keypress (or keydown) and keyrelease (or keyup).

HTH

Share this post


Link to post
Share on other sites
Whenever you hit any arrow key, it sends two codes, one is the scan code for when any arrow key is being pressed (224) the second is the actual key code that's being pressed.

Here's something I did not too long ago:


/*by »RëLïÉÑt«*/
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>

#define KEY_CR 0xD //Carriage Return
#define KEY_NL 0xA //Newline
#define KEY_CURSOR 224
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_RIGHT 77
#define KEY_LEFT 75
#define SET_ZERO 0

int Width = 0;
int Height = 0;

void XDraw(void);
void XMove(void);
void XClean(void);

typedef struct _XDOS {
DWORD iWritten;
CONSOLE_CURSOR_INFO iCursorInfo;
CONSOLE_SCREEN_BUFFER_INFO iWinInfo;
HANDLE iHandleStdin;
HANDLE iHandleStdout;
COORD iPos;
}XDOS;

XDOS Xdos;

main()
{
SetConsoleTitle("-*>|>RelIENt<|<*-");

Xdos.iHandleStdout = GetStdHandle(STD_OUTPUT_HANDLE);
Xdos.iHandleStdin = GetStdHandle(STD_INPUT_HANDLE);

GetConsoleScreenBufferInfo(Xdos.iHandleStdout, &Xdos.iWinInfo);

Xdos.iPos.X = Xdos.iWinInfo.srWindow.Right / 2;
Xdos.iPos.Y = Xdos.iWinInfo.srWindow.Bottom / 2;

Width = Xdos.iPos.X * 2;
Height = Xdos.iPos.Y * 2;

Xdos.iCursorInfo.dwSize = 1;
Xdos.iCursorInfo.bVisible = false;
SetConsoleCursorInfo(Xdos.iHandleStdout, &Xdos.iCursorInfo);
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);

XDraw();

while (true)
{
if (kbhit())
{
if (_getch() == KEY_CURSOR)
{
XClean();
XMove();
XDraw();
}
}
Sleep(1);

}
}

void XDraw(void)
{
int x = Xdos.iPos.X;
int y = Xdos.iPos.Y;

for (int n = 0; n < 4; ++n)
{
if (n == 1)
Xdos.iPos.X += 2;
else if (n == 2)
{
Xdos.iPos.Y += 2;
Xdos.iPos.X -= 2;
}
else if (n == 3)
Xdos.iPos.X += 2;

SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
putchar(219);
}

Xdos.iPos.X = x;
Xdos.iPos.Y = y;
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
}

void XMove(void)
{
int key;

switch (key = _getch())
{

case KEY_UP:
Xdos.iPos.Y == SET_ZERO ? Xdos.iPos.Y = Xdos.iPos.Y : Xdos.iPos.Y--;
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
break;
case KEY_LEFT:
Xdos.iPos.X == SET_ZERO ? Xdos.iPos.X = Xdos.iPos.X : Xdos.iPos.X--;
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
break;
case KEY_RIGHT:
Xdos.iPos.X == (Width-2) ? Xdos.iPos.X = Xdos.iPos.X : Xdos.iPos.X++;
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
break;
case KEY_DOWN:
Xdos.iPos.Y == (Height-2) ? Xdos.iPos.Y = Xdos.iPos.Y : Xdos.iPos.Y++;
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
break;

default: ;

}
}

void XClean(void)
{
int x = Xdos.iPos.X;
int y = Xdos.iPos.Y;

for (int n = 0; n < 4; ++n)
{
if (n == 1)
Xdos.iPos.X += 2;
else if (n == 2)
{
Xdos.iPos.Y += 2;
Xdos.iPos.X -= 2;
}
else if (n == 3)
Xdos.iPos.X += 2;

SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
putchar(' ');
}
Xdos.iPos.X = x;
Xdos.iPos.Y = y;
SetConsoleCursorPosition(Xdos.iHandleStdout, Xdos.iPos);
}



It draws four boxes to the screen and repositions them based on the new cordinates when you press an arrow key.

It has collision detection aswell. Mess with it for awhile and if you have anymore questions, post again.

Share this post


Link to post
Share on other sites
If you dont want to use kbhit() and getch() you can just check the bKeyDown member of the KEY_EVENT_RECORD struct. Choose to handle the case when the key is pressed (bKeyDown == TRUE) or when the key is released (bKeyDown == FALSE).

Share this post


Link to post
Share on other sites

This topic is 4736 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this