PDA

Prikaži potpunu verziju : SFML (C++) problem


GrimReaper
26.2.2012, 18:01
Izvinjavam se ako je ovo možda glupo pitanje, ali relativno sam nov u ovome i nikako ne mogu da rešim sledeći problem. Pokušavam da nateram sprite da simulira skok, i to tako što će neko vreme da ide naviše, a posle toga počinje da ide naniže. Pokušao sam da uradim to uz pomoć promenljive sf::Clock, ovako nekako:

if (sf::Keyboard::IsKeyPressed(sf::Keyboard::Space))
{
clock.Restart();
while (clock.GetElapsedTime().AsMilliseconds() < 1000)
sprite.SetPosition(sprite.GetPosition().x, -Speed * clock.GetElapsedTime().AsMilliseconds() * 0.01);
while ((clock.GetElapsedTime().AsMilliseconds() > 1000) && (clock.GetElapsedTime().AsMilliseconds() < 2000))
sprite.SetPosition(sprite.GetPosition().x, Speed * clock.GetElapsedTime().AsMilliseconds() * 0.01);
}

ali sve što sam uspeo da dobijem jeste da sprite ništa ne radi neko vreme (pretpostavljam 2 sekunde), a onda prosto nestane s ekrana. Jel ima neko neku ideju?

Belphegor
26.2.2012, 18:12
Treba malo da promenis logiku koda, pseudo:

const vector2 gravity(0.0f, 0.98f);
const float jump_speed = 4.0f;
bool jumping = false;
float current_time_in_air = 0.0f;
const float max_time_in_air = 2.0f;
const float move_speed = 4.0f;

...
...

float delta_time = clock.GetElapsedTime();// ako im ovo oznacava vreme provedeno izmedju "frejmova"

vector2 pos = sprite.position;// last frame position

pos -= gravity * delta_time;

if(pos.y < ground_level.y)
{
pos.y = ground_level.y;
}


if( key left pressed )
{
pos.x -= move_speed * delta_time;
}

if( key right pressed )
{
pos.x += move_speed * delta_time;
}

if( key space pressed )
{
if( !jumping && standing_on_the_ground)
{
jumping = true;
}
}

if(jumping)
{
current_time_in_air += delta_time;
if(current_time_in_air > max_time_in_air)
{
current_time_in_air = 0.0f;// reset na 0
jumping = false;
}
else
{
vector2 jump_direction = vector2(0.0f, jump_speed * delta_time);
pos += jump_direction;
}
}

sprite.position = pos;// new position
sprite.draw();
EDIT: promenuo sam malo pseudo kod.
EDIT2: primetio sam gresku pa sam ponovo editovao.:o :D
EDIT3: more edits. :D

Belphegor
26.2.2012, 20:44
Spakovao sam na brzaka mali demo :D :

2PTwyebleOQ


#define _WIN32_WINNT 0x0501
#include <windows.h>

#define ID_TIMER 100

LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

struct vector2
{
float x, y;
vector2(float x, float y) : x(x), y(y) {}
vector2(const vector2& o) : x(o.x), y(o.y) {}
vector2& operator = (const vector2& o){
x = o.x; y = o.y;
return *this;
}
};

vector2 operator * (const vector2& l, const vector2& r){
return vector2(l.x * r.x, l.y * r.y);
}

vector2& operator -= (vector2& l, vector2& r){
l.x -= r.x;
l.y -= r.y;
return l;
}

vector2& operator += (vector2& l, vector2& r){

l.x += r.x;
l.y += r.y;
return l;
}

vector2 operator * (const vector2& l, float scalar){
return vector2(l.x * scalar, l.y * scalar);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wndClass;
memset(&wndClass, 0, sizeof(WNDCLASS));
wndClass.hInstance = GetModuleHandle(0);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = reinterpret_cast<WNDPROC>( WindowProc );
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.lpszClassName = TEXT("SpriteClass");
wndClass.hbrBackground = GetSysColorBrush(COLOR_3DFACE);

DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_MINIMIZEBOX;

RegisterClass(&wndClass);

HWND hwnd = CreateWindow(
TEXT("SpriteClass"), TEXT("Game"), style,
100, 50, 600, 400,
nullptr, nullptr, GetModuleHandle(0), nullptr);

ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);

MSG msg = {0};
while(GetMessage(&msg, NULL, 0, 0))
{
if(IsDialogMessage(hwnd, &msg))
continue;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static const float sprite_size = 30.0f;
static const float ground_level_y = 300.0f - sprite_size;
static const float delta_time = 1.1f;
static vector2 sprite_position(250.0f, ground_level_y);
static vector2 pos = sprite_position;
const vector2 gravity(0.0f, 1.5f);
static const float jump_speed = 4.0f;
static bool jumping = false;
static float current_time_in_air = 0.0f;
static const float max_time_in_air = 20.0f;
static const float move_speed = 2.0f;
static bool standing_on_ground = true;

switch(msg)
{
case WM_CREATE:
{
SetTimer(hWnd, ID_TIMER, 10, 0);
}break;
case WM_TIMER:
{
if(GetKeyState('A') & 0x80)
pos.x -= move_speed * delta_time;

if(GetKeyState('D') & 0x80)
pos.x += move_speed * delta_time;

if(GetKeyState(VK_SPACE) & 0x80)
{
if( !jumping && standing_on_ground )
{
jumping = true;
}
}


pos += gravity * delta_time;

if(pos.y > ground_level_y)
{
pos.y = ground_level_y;
standing_on_ground = true;
}

if(jumping)
{
standing_on_ground = false;
current_time_in_air += delta_time;
if(current_time_in_air > max_time_in_air)
{
current_time_in_air = 0.0f;// reset na 0
jumping = false;
}
else
{
vector2 jump_direction = vector2(0.0f, jump_speed * delta_time);
pos -= jump_direction;
}
}

sprite_position = pos;
InvalidateRect(hWnd, 0, TRUE);
}break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

Ellipse(hdc, sprite_position.x, sprite_position.y, sprite_position.x + sprite_size, sprite_position.y + sprite_size);

MoveToEx(hdc, 0, 300, nullptr);
LineTo(hdc, 600, 300);

EndPaint(hWnd, &ps);
}break;
case WM_DESTROY:
{
KillTimer(hWnd, ID_TIMER);
PostQuitMessage(0);
}break;
default:
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}break;
};
return 0;
}
samo sto je ovde +y "na dole" pa sam morao zameniti operacije -/+.

GrimReaper
27.2.2012, 13:42
Hvala, konačno sam ukapirao kako funkcionišu frejmovi. :)