//#include <windows.h>
#include "dxlib.h"
#define CX 1024
#define CY 768
#define BPP 16
#define WHITE GetColor( 255, 255, 255 )
#define GRAY(a) GetColor( a, a, a )
#define ACCELL 7.5
#define GRAVITY 15.0
#define CSLOPE 7.5
#define RESIST 2.5
#define JUMP 300.0
#define FERROR 2.5
#define PSIZE 8
double GetSlope( VECTOR* fdata, int numdata, int x );
double GetFloor( VECTOR* fdata, int numdata, int x );
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nCmdShow)
{
SetGraphMode( CX, CY, BPP );
ChangeWindowMode( TRUE );
if( DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK );
VECTOR floors[] = { { 0, 64, 0 }, { 100, 64, 0 }, { 200, 96, 0 }, { 250, 104, 0 },
{ 500, 32, 0 }, { 800, 32, 0 }, { 1000, 256, 0 }, { 1500, 128, 0 }, { 2000, 64, 0 },
{ 2500, 96, 0 }, { 3000, 128, 0 }, { 3200, 160, 0 }, { 3400, 10, 0 }, { 5000, 64, 0 } };
int elements = sizeof(floors) / sizeof(VECTOR);
VECTOR player = { 50, 100, 0 };
VECTOR vec = { 0, 0 };
int cam_x;
double floor_y;
int pre_time, cur_time;
double past_time;
int bOnTheFloor = FALSE;
int bDrawAll = TRUE;
int bPreDKey = FALSE;
int bPreSPKey = FALSE;
pre_time = GetCurrentTime();
while ( ProcessMessage() != -1 ) {
if ( CheckHitKey( KEY_INPUT_ESCAPE ) )
break;
if ( CheckHitKey( KEY_INPUT_D ) ) {
if ( !bPreDKey )
bDrawAll = !bDrawAll;
bPreDKey = TRUE;
}
else
bPreDKey = FALSE;
cur_time = GetCurrentTime();
past_time = (double)( cur_time - pre_time) / 1000.0;
pre_time = cur_time;
if ( CheckHitKey( KEY_INPUT_RIGHT ) ) vec.x += ( bOnTheFloor ? ACCELL : (ACCELL * 0.25) );
if ( CheckHitKey( KEY_INPUT_LEFT ) ) vec.x -= ( bOnTheFloor ? ACCELL : (ACCELL * 0.25) );
if ( bOnTheFloor ) {
vec.x -= GetSlope( floors, elements, player.x ) * CSLOPE;
if ( GetSlope( floors, elements, player.x ) * vec.x < 0.0 )
vec.y -= abs( GetSlope( floors, elements, player.x ) * 500 );
}
if ( vec.x > 0.0 ) {
if ( ( vec.x -= ( bOnTheFloor ? RESIST : (RESIST * 0.25) ) ) < 0.0 ) vec.x = 0.0;
}
if ( vec.x < 0.0 ) {
if ( ( vec.x += ( bOnTheFloor ? RESIST : (RESIST * 0.25) ) ) > 0.0 ) vec.x = 0.0;
}
if ( CheckHitKey( KEY_INPUT_SPACE ) ) {
if ( !bPreSPKey && bOnTheFloor )
vec.y = JUMP;
bPreSPKey = TRUE;
}
else
bPreSPKey = FALSE;
player.x += vec.x * past_time;
player.y += vec.y * past_time;
vec.y -= GRAVITY;
floor_y = GetFloor( floors, elements, player.x );
if ( floor_y + FERROR > player.y ) {
player.y = floor_y;
vec.y = 0.0;
bOnTheFloor = TRUE;
}
else {
bOnTheFloor = FALSE;
}
cam_x = player.x - (CX >> 1);
ClearDrawScreen();
for ( int i = 0; i < elements - 1; i++ ) {
DrawLine( floors[i].x - cam_x, CY - floors[i].y, floors[i+1].x - cam_x, CY - floors[i+1].y, WHITE );
}
if ( bDrawAll ) {
for ( i = floors[0].x; i < floors[elements - 1].x; i++ ) {
DrawLine( i - cam_x, CY - GetFloor( floors, elements, i ), i - cam_x, CY, GRAY( 64 ) );
}
}
DrawBox( player.x - PSIZE - cam_x, CY - player.y - (PSIZE << 1), player.x + PSIZE - cam_x, CY - player.y, GetColor( 128, 128, 255 ), TRUE );
DrawFormatString( 0, 0, WHITE, "← →で移動" );
DrawFormatString( 0, 24, WHITE, "スペースキーでジャンプ" );
DrawFormatString( 0, 48, WHITE, "重い時は\"D\"キーで地面非表示" );
ScreenFlip();
}
DxLib_End();
return 0;
}
double GetSlope( VECTOR* fdata, int numdata, int x ) {
double slope;
for ( int i = 0; i < numdata - 1; i++ ) {
if ( fdata[i].x <= x && x < fdata[i+1].x )
break;
}
if ( i >= numdata - 1 )
slope = 0;
else
slope = (double)(fdata[i+1].y - fdata[i].y) / (double)(fdata[i+1].x - fdata[i].x);
return slope;
}
double GetFloor( VECTOR* fdata, int numdata, int x ) {
double floor_y;
for ( int i = 0; i < numdata - 1; i++ ) {
if ( fdata[i].x <= x && x < fdata[i+1].x )
break;
}
if ( i >= numdata - 1 )
floor_y = -1000;
else
floor_y = (double)(fdata[i+1].y - fdata[i].y) / (double)(fdata[i+1].x - fdata[i].x) * (double)(x - fdata[i].x) + fdata[i].y;
return floor_y;
}
Ly8jaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSAiZHhsaWIuaCIKCiNkZWZpbmUgQ1gJCQkxMDI0CiNkZWZpbmUgQ1kJCQk3NjgKI2RlZmluZSBCUFAJCQkxNgojZGVmaW5lIFdISVRFCQlHZXRDb2xvciggMjU1LCAyNTUsIDI1NSApCiNkZWZpbmUgR1JBWShhKQkJR2V0Q29sb3IoIGEsIGEsIGEgKQoKI2RlZmluZSBBQ0NFTEwJCTcuNQojZGVmaW5lIEdSQVZJVFkJCTE1LjAKI2RlZmluZSBDU0xPUEUJCTcuNQojZGVmaW5lIFJFU0lTVAkJMi41CiNkZWZpbmUgSlVNUAkJMzAwLjAKI2RlZmluZSBGRVJST1IJCTIuNQojZGVmaW5lIFBTSVpFCQk4Cgpkb3VibGUgR2V0U2xvcGUoIFZFQ1RPUiogZmRhdGEsIGludCBudW1kYXRhLCBpbnQgeCApOwpkb3VibGUgR2V0Rmxvb3IoIFZFQ1RPUiogZmRhdGEsIGludCBudW1kYXRhLCBpbnQgeCApOwoKaW50IFdJTkFQSSBXaW5NYWluKEhJTlNUQU5DRSBoSW5zdGFuY2UsIEhJTlNUQU5DRSBoUHJldiwgTFBTVFIgbHBDbWRMaW5lLCBpbnQgbkNtZFNob3cpCnsKCVNldEdyYXBoTW9kZSggQ1gsIENZLCBCUFAgKTsKCUNoYW5nZVdpbmRvd01vZGUoIFRSVUUgKTsKCWlmKCBEeExpYl9Jbml0KCkgPT0gLTEgKQlyZXR1cm4gLTE7CglTZXREcmF3U2NyZWVuKCBEWF9TQ1JFRU5fQkFDSyApOwoKCVZFQ1RPUiBmbG9vcnNbXSA9IHsgeyAwLCA2NCwgMCB9LCB7IDEwMCwgNjQsIDAgfSwgeyAyMDAsIDk2LCAwIH0sIHsgMjUwLCAxMDQsIDAgfSwKCQl7IDUwMCwgMzIsIDAgfSwgeyA4MDAsIDMyLCAwIH0sIHsgMTAwMCwgMjU2LCAwIH0sIHsgMTUwMCwgMTI4LCAwIH0sIHsgMjAwMCwgNjQsIDAgfSwKCQl7IDI1MDAsIDk2LCAwIH0sIHsgMzAwMCwgMTI4LCAwIH0sIHsgMzIwMCwgMTYwLCAwIH0sIHsgMzQwMCwgMTAsIDAgfSwgeyA1MDAwLCA2NCwgMCB9IH07CglpbnQgZWxlbWVudHMgPSBzaXplb2YoZmxvb3JzKSAvIHNpemVvZihWRUNUT1IpOwoJVkVDVE9SIHBsYXllciA9IHsgNTAsIDEwMCwgMCB9OwoJVkVDVE9SIHZlYyA9IHsgMCwgMCB9OwoJaW50IGNhbV94OwoJZG91YmxlIGZsb29yX3k7CglpbnQgcHJlX3RpbWUsIGN1cl90aW1lOwoJZG91YmxlIHBhc3RfdGltZTsKCWludCBiT25UaGVGbG9vciA9IEZBTFNFOwoJaW50IGJEcmF3QWxsID0gVFJVRTsKCWludCBiUHJlREtleSA9IEZBTFNFOwoJaW50IGJQcmVTUEtleSA9IEZBTFNFOwoKCXByZV90aW1lID0gR2V0Q3VycmVudFRpbWUoKTsKCXdoaWxlICggUHJvY2Vzc01lc3NhZ2UoKSAhPSAtMSApCXsKCQlpZiAoIENoZWNrSGl0S2V5KCBLRVlfSU5QVVRfRVNDQVBFICkgKQoJCQlicmVhazsKCQlpZiAoIENoZWNrSGl0S2V5KCBLRVlfSU5QVVRfRCApICkgewoJCQlpZiAoICFiUHJlREtleSApCgkJCQliRHJhd0FsbCA9ICFiRHJhd0FsbDsKCQkJYlByZURLZXkgPSBUUlVFOwoJCX0KCQllbHNlCgkJCWJQcmVES2V5ID0gRkFMU0U7CgkJY3VyX3RpbWUgID0gR2V0Q3VycmVudFRpbWUoKTsKCQlwYXN0X3RpbWUgPSAoZG91YmxlKSggY3VyX3RpbWUgLSBwcmVfdGltZSkgLyAxMDAwLjA7CgkJcHJlX3RpbWUgID0gY3VyX3RpbWU7CgoJCWlmICggQ2hlY2tIaXRLZXkoIEtFWV9JTlBVVF9SSUdIVCApICkJCQkJCXZlYy54ICs9ICggYk9uVGhlRmxvb3IgPyBBQ0NFTEwgOiAoQUNDRUxMICogMC4yNSkgKTsKCQlpZiAoIENoZWNrSGl0S2V5KCBLRVlfSU5QVVRfTEVGVCApICkJCQkJCXZlYy54IC09ICggYk9uVGhlRmxvb3IgPyBBQ0NFTEwgOiAoQUNDRUxMICogMC4yNSkgKTsKCQlpZiAoIGJPblRoZUZsb29yICkgewoJCQl2ZWMueCAtPSBHZXRTbG9wZSggZmxvb3JzLCBlbGVtZW50cywgcGxheWVyLnggKSAqIENTTE9QRTsKCQkJaWYgKCBHZXRTbG9wZSggZmxvb3JzLCBlbGVtZW50cywgcGxheWVyLnggKSAqIHZlYy54IDwgMC4wICkKCQkJCXZlYy55IC09IGFicyggR2V0U2xvcGUoIGZsb29ycywgZWxlbWVudHMsIHBsYXllci54ICkgKiA1MDAgKTsKCQl9CgkJaWYgKCB2ZWMueCA+IDAuMCApIHsKCQkJaWYgKCAoIHZlYy54IC09ICggYk9uVGhlRmxvb3IgPyBSRVNJU1QgOiAoUkVTSVNUICogMC4yNSkgKSApIDwgMC4wICkJdmVjLnggPSAwLjA7CgkJfQoJCWlmICggdmVjLnggPCAwLjAgKSB7CgkJCWlmICggKCB2ZWMueCArPSAoIGJPblRoZUZsb29yID8gUkVTSVNUIDogKFJFU0lTVCAqIDAuMjUpICkgKSA+IDAuMCApCXZlYy54ID0gMC4wOwoJCX0KCQkKCQlpZiAoIENoZWNrSGl0S2V5KCBLRVlfSU5QVVRfU1BBQ0UgKSApIHsKCQkJaWYgKCAhYlByZVNQS2V5ICYmIGJPblRoZUZsb29yICkKCQkJCXZlYy55ID0gSlVNUDsKCQkJYlByZVNQS2V5ID0gVFJVRTsKCQl9CgkJZWxzZQoJCQliUHJlU1BLZXkgPSBGQUxTRTsKCQlwbGF5ZXIueCArPSB2ZWMueCAqIHBhc3RfdGltZTsKCQlwbGF5ZXIueSArPSB2ZWMueSAqIHBhc3RfdGltZTsKCgkJdmVjLnkgLT0gR1JBVklUWTsKCgkJZmxvb3JfeSA9IEdldEZsb29yKCBmbG9vcnMsIGVsZW1lbnRzLCBwbGF5ZXIueCApOwoJCWlmICggZmxvb3JfeSArIEZFUlJPUiA+IHBsYXllci55ICkgewoJCQlwbGF5ZXIueSA9IGZsb29yX3k7CgkJCXZlYy55ID0gMC4wOwoJCQliT25UaGVGbG9vciA9IFRSVUU7CgkJfQoJCWVsc2UgewoJCQliT25UaGVGbG9vciA9IEZBTFNFOwoJCX0KCgkJY2FtX3ggPSBwbGF5ZXIueCAtIChDWCA+PiAxKTsKCgkJQ2xlYXJEcmF3U2NyZWVuKCk7CgoJCWZvciAoIGludCBpID0gMDsgaSA8IGVsZW1lbnRzIC0gMTsgaSsrICkgewoJCQlEcmF3TGluZSggZmxvb3JzW2ldLnggLSBjYW1feCwgQ1kgLSBmbG9vcnNbaV0ueSwgZmxvb3JzW2krMV0ueCAtIGNhbV94LCBDWSAtIGZsb29yc1tpKzFdLnksIFdISVRFICk7CgkJfQoJCWlmICggYkRyYXdBbGwgKSB7CgkJCWZvciAoIGkgPSBmbG9vcnNbMF0ueDsgaSA8IGZsb29yc1tlbGVtZW50cyAtIDFdLng7IGkrKyApIHsKCQkJCURyYXdMaW5lKCBpIC0gY2FtX3gsIENZIC0gR2V0Rmxvb3IoIGZsb29ycywgZWxlbWVudHMsIGkgKSwgaSAtIGNhbV94LCBDWSwgR1JBWSggNjQgKSApOwoJCQl9CgkJfQoJCURyYXdCb3goIHBsYXllci54IC0gUFNJWkUgLSBjYW1feCwgQ1kgLSBwbGF5ZXIueSAtIChQU0laRSA8PCAxKSwgcGxheWVyLnggKyBQU0laRSAtIGNhbV94LCBDWSAtIHBsYXllci55LCBHZXRDb2xvciggMTI4LCAxMjgsIDI1NSApLCBUUlVFICk7CgoJCURyYXdGb3JtYXRTdHJpbmcoIDAsIDAsIFdISVRFLCAi4oaQIOKGkuOBp+enu+WLlSIgKTsKCQlEcmF3Rm9ybWF0U3RyaW5nKCAwLCAyNCwgV0hJVEUsICLjgrnjg5rjg7zjgrnjgq3jg7zjgafjgrjjg6Pjg7Pjg5ciICk7CgkJRHJhd0Zvcm1hdFN0cmluZyggMCwgNDgsIFdISVRFLCAi6YeN44GE5pmC44GvXCJEXCLjgq3jg7zjgaflnLDpnaLpnZ7ooajnpLoiICk7CgoJCVNjcmVlbkZsaXAoKTsKCX0KCglEeExpYl9FbmQoKTsKCglyZXR1cm4gMDsKfQoKZG91YmxlIEdldFNsb3BlKCBWRUNUT1IqIGZkYXRhLCBpbnQgbnVtZGF0YSwgaW50IHggKSB7Cglkb3VibGUgc2xvcGU7CgoJZm9yICggaW50IGkgPSAwOyBpIDwgbnVtZGF0YSAtIDE7IGkrKyApIHsKCQlpZiAoIGZkYXRhW2ldLnggPD0geCAmJiB4IDwgZmRhdGFbaSsxXS54ICkKCQkJYnJlYWs7Cgl9CglpZiAoIGkgPj0gbnVtZGF0YSAtIDEgKQoJCXNsb3BlID0gMDsKCWVsc2UKCQlzbG9wZSA9IChkb3VibGUpKGZkYXRhW2krMV0ueSAtIGZkYXRhW2ldLnkpIC8gKGRvdWJsZSkoZmRhdGFbaSsxXS54IC0gZmRhdGFbaV0ueCk7CgoJcmV0dXJuIHNsb3BlOwp9Cgpkb3VibGUgR2V0Rmxvb3IoIFZFQ1RPUiogZmRhdGEsIGludCBudW1kYXRhLCBpbnQgeCApIHsKCWRvdWJsZSBmbG9vcl95OwoKCWZvciAoIGludCBpID0gMDsgaSA8IG51bWRhdGEgLSAxOyBpKysgKSB7CgkJaWYgKCBmZGF0YVtpXS54IDw9IHggJiYgeCA8IGZkYXRhW2krMV0ueCApCgkJCWJyZWFrOwoJfQoJaWYgKCBpID49IG51bWRhdGEgLSAxICkKCQlmbG9vcl95ID0gLTEwMDA7CgllbHNlCgkJZmxvb3JfeSA9IChkb3VibGUpKGZkYXRhW2krMV0ueSAtIGZkYXRhW2ldLnkpIC8gKGRvdWJsZSkoZmRhdGFbaSsxXS54IC0gZmRhdGFbaV0ueCkgKiAoZG91YmxlKSh4IC0gZmRhdGFbaV0ueCkgKyBmZGF0YVtpXS55OwoKCXJldHVybiBmbG9vcl95Owp9