killermannnnn Temat założony przez niniejszego użytkownika |
C++ Builder 6 -> Problem z funkcja OnKeyDown() » 2015-01-10 19:26:38 Robię sobie grę typu Snake i nie działa mi sterowanie klawiszami mimo, że wszystko wygląda dobrze. Nie ważne co wpiszę w funkcji, ona w ogóle nie reaguje na żaden klawisz. Co jest źle? Cały projekt: https://www.dropbox.com/sh/n3hrr5dejc35kfh/AACKC15BkKZ6H3dYft69xRjla?dl=0 main.cpp: (funkcja OnKeyDown() na samym końcu
#include <vcl.h> #pragma hdrstop
#include "Unit1.h" #include <vector> #include <algorithm>
#pragma package(smart_init) #pragma resource "*.dfm"
using namespace std;
TForm1 * Form1;
__fastcall TForm1::TForm1( TComponent * Owner ) : TForm( Owner ) { }
enum kierunek { gora, dol, lewo, prawo }; kierunek kierunek_weza;
struct PktJedzenia; struct PktWeza;
vector < PktJedzenia > Jedzonko; vector < PktWeza > Waz;
void sprawdz_czy_sie_nie_nakladaja_punkty();
struct PktJedzenia { int x, y; PktJedzenia( int x, int y ) : x( x ) , y( y ) { } bool operator <( const PktJedzenia & temp ) const { if( x != temp.x ) return x < temp.x; else return y < temp.y; } };
struct PktWeza { int x, y; PktWeza( int x, int y ) : x( x ) , y( y ) { } };
void rysuj_plansze() { Form1->Canvas->Pen->Color = clRed; Form1->Canvas->Brush->Color = clRed; Form1->Canvas->Rectangle( 0, 0, 500, 500 ); }
void rysuj_punkty() { Jedzonko.erase( Jedzonko.begin(), Jedzonko.end() ); int ile = random( 50 ) + 20; Form1->Canvas->Pen->Color = clBlue; Form1->Canvas->Brush->Color = clBlue; for( int i = 0; i < ile; i++ ) { Jedzonko.push_back( PktJedzenia( random( 24 ) * 20, random( 24 ) * 20 ) ); } sprawdz_czy_sie_nie_nakladaja_punkty(); for( int i = 0; i < ile; i++ ) { Form1->Canvas->Rectangle( Jedzonko[ i ].x, Jedzonko[ i ].y, Jedzonko[ i ].x + 20, Jedzonko[ i ].y + 20 ); } }
void sprawdz_czy_sie_nie_nakladaja_punkty() { sort( Jedzonko.begin(), Jedzonko.end() ); for( int i = 1; i < Jedzonko.size(); i++ ) { if( Jedzonko[ i ].x == Jedzonko[ i-- ].x && Jedzonko[ i ].y == Jedzonko[ i-- ].y ) { Jedzonko.erase( Jedzonko.begin() + i, Jedzonko.begin() + i ); } } }
void generuj_weza() { Waz.erase( Waz.begin(), Waz.end() ); int x = random( 5 ) * 20 + 200; int y = random( 5 ) * 20 + 200; Waz.push_back( PktWeza( x, y ) ); Waz.push_back( PktWeza( x, y - 20 ) ); }
void rysuj_weza() { Form1->Canvas->Pen->Color = clGreen; Form1->Canvas->Brush->Color = clGreen; for( int i = 0; i < Waz.size(); i++ ) { Form1->Canvas->Rectangle( Waz[ i ].x, Waz[ i ].y, Waz[ i ].x + 20, Waz[ i ].y + 20 ); } }
void ruszaj_wezem( kierunek gdzie ) { Form1->Canvas->Pen->Color = clRed; Form1->Canvas->Brush->Color = clRed; Form1->Canvas->Rectangle( Waz[ Waz.size() - 1 ].x, Waz[ Waz.size() - 1 ].y, Waz[ Waz.size() - 1 ].x + 20, Waz[ Waz.size() - 1 ].y + 20 ); for( int i = Waz.size() - 1; i >= 1; i-- ) { Waz[ i ].x = Waz[ i - 1 ].x; Waz[ i ].y = Waz[ i - 1 ].y; } if( gdzie == gora ) { Waz[ 0 ].y = Waz[ 0 ].y - 20; } else if( gdzie == dol ) { Waz[ 0 ].y = Waz[ 0 ].y + 20; } else if( gdzie == lewo ) { Waz[ 0 ].x = Waz[ 0 ].x - 20; } else if( gdzie == prawo ) { Waz[ 0 ].x = Waz[ 0 ].x + 20; } }
void __fastcall TForm1::Button1Click( TObject * Sender ) { rysuj_plansze(); rysuj_punkty(); generuj_weza(); Timer1->Enabled = true; }
void __fastcall TForm1::Timer1Timer( TObject * Sender ) { rysuj_weza(); ruszaj_wezem( kierunek_weza ); }
void __fastcall TForm1::FormKeyDown( TObject * Sender, WORD & Key, TShiftState Shift ) { switch( Key ) { case VK_UP: kierunek_weza = gora; break; case VK_DOWN: kierunek_weza = dol; break; case VK_LEFT: kierunek_weza = lewo; break; case VK_RIGHT: kierunek_weza = prawo; break; } }
|
|
Monika90 |
» 2015-01-10 20:31:38 Być może okno dialogowe nie ma fokusu, więc powiadomienia o naciśniętych klawiszach trafiają gdzieś indziej, np. do ostatnio klikniętego przycisku. |
|
killermannnnn Temat założony przez niniejszego użytkownika |
» 2015-01-10 20:33:39 A jak to naprawić ?
Sprawdzałem przenosząc funkcję do Guzika ale też nic. Np. OnClick() myszki działa dobrze |
|
akwes |
» 2015-01-10 23:07:01 Rozwiązanie tego problemu nie rozwiąże problemu projektowego jaki jest w Twojej aplikacji.
Zdarzenie, którego próbujesz użyć służy do czegoś innego. To co chcesz zrealizować wymaga użycia TTimera oraz GetKeyState(). Timer zapewni Ci niezależną prędkość poruszania się i kontroli nad wężem, niezależnie od sprzętu na jakim będzie uruchomiana gra. Natomiast zdarzenia i ich ilość na sekundę jest zależna od tego, jak wydajny masz komputer. Bo nie chcesz aby gra działała z różną prędkością na różnych komputerach :)?
// Edit, widzę, że używasz TTimera, ale tylko do rysowania. Używaj go również do liczenia fizyki oraz ruchu. |
|
Monika90 |
» 2015-01-10 23:11:41 Sprawdź czy działają inne klawisze niż strzałki. |
|
killermannnnn Temat założony przez niniejszego użytkownika |
» 2015-01-11 11:31:16 @akwes Dzięki za pomoc.
@Monika90 Żaden klawisz nie działa ale już rozwiązałem program użyciem GetKeyState() |
|
« 1 » |