- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 C++ 自学 SDL、OpenGL 等。在线教程帮助我创建了一个在屏幕上移动的盒子和一个盒子无法通过的壁架...
我没能找到解释和展示如何让盒子跳跃或四处跳跃的教程。理想情况下,我希望我的盒子能像老式马里奥一样向前移动并跳上窗台。
我不确定这是否可以用 SDL 完成?我猜需要添加一些东西才能使盒子在按下向上后返回地面......我尝试了 up
/down
键,并试图让盒子在按下后返回地面,但它没有用。我试过将盒子放在地上,但向上键不起作用。我也试过一旦按下向上并且盒子已经移动以使盒子下降相同的距离......我有点明白它需要如何实现(我认为),我只是不太了解 C++ 来编写它,或者它是否可以完成。
目前我可以向左或向右和向上移动,但他仍然漂浮在空中:(
这是我的代码:
#include "SDL.h"
#include "SDL_image.h"
#include <string>
const int SCREEN_WIDTH = 480;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
const int FRAMES_PER_SECOND = 20;
const int SQUARE_WIDTH = 20;
const int SQUARE_HEIGHT = 20;
SDL_Surface *square = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;
SDL_Rect wall;
class Square{
private:
SDL_Rect box;
int xVel, yVel;
public:
Square();
void handle_input();
void move();
void show();};
class Timer{
private:
int startTicks;
int pausedTicks;
bool paused;
bool started;
public:
Timer();
void start();
void stop();
void pause();
void unpause();
int get_ticks();
bool is_started();
bool is_paused();};
SDL_Surface *load_image( std::string filename ){
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = IMG_Load( filename.c_str() );
if( loadedImage != NULL )
{
optimizedImage = SDL_DisplayFormat( loadedImage );
SDL_FreeSurface( loadedImage );
if( optimizedImage != NULL )
{
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 237, 145, 33 ) );//optimizedImage->format, 0, 0xFF, 0xFF
}
}
return optimizedImage;}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL ){
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface( source, clip, destination, &offset );}
bool check_collision( SDL_Rect A, SDL_Rect B ){
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
leftA = A.x;
rightA = A.x + A.w;
topA = A.y;
bottomA = A.y + A.h;
leftB = B.x;
rightB = B.x + B.w;
topB = B.y;
bottomB = B.y + B.h;
if( bottomA <= topB ){return false;}
if( topA >= bottomB ){return false;}
if( rightA <= leftB ){return false;}
if( leftA >= rightB ){return false;}
return true;}
bool init(){
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ){return false;}
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
if( screen == NULL ){return false;}
SDL_WM_SetCaption( "Move the Square", NULL );
return true;}
bool load_files(){
square = load_image( "square.bmp" );
if( square == NULL ){return false;}
return true;}
void clean_up(){
SDL_FreeSurface( square );
SDL_Quit();}
Square::Square(){
box.x = 50;
box.y = 360;
box.w = SQUARE_WIDTH;
box.h = SQUARE_HEIGHT;
xVel = 0;
yVel = 0;}
void Square::handle_input(){
if( event.type == SDL_KEYDOWN ){
switch( event.key.keysym.sym ){
case SDLK_UP: yVel -= SQUARE_HEIGHT / 2; break;
//case SDLK_DOWN: yVel += SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel += SQUARE_WIDTH / 2; break;}}
else if( event.type == SDL_KEYUP ){
switch( event.key.keysym.sym ){
case SDLK_UP: yVel += SQUARE_HEIGHT / 2; break;
//case SDLK_DOWN: yVel -= SQUARE_HEIGHT / 2; break;
case SDLK_LEFT: xVel += SQUARE_WIDTH / 2; break;
case SDLK_RIGHT: xVel -= SQUARE_WIDTH / 2; break;}}}
void Square::move(){
box.x += xVel;
if( ( box.x < 0 ) || ( box.x + SQUARE_WIDTH > SCREEN_WIDTH ) || ( check_collision( box, wall ) ) ){
box.x -= xVel;}
box.y += yVel;
if( ( box.y < 0 ) || ( box.y + SQUARE_HEIGHT > SCREEN_HEIGHT ) || ( check_collision( box, wall ) ) ){
box.y -= yVel;}}
void Square::show(){
apply_surface( box.x, box.y, square, screen );}
Timer::Timer(){
startTicks = 0;
pausedTicks = 0;
paused = false;
started = false;}
void Timer::start(){
started = true;
paused = false;
startTicks = SDL_GetTicks();}
void Timer::stop(){
started = false;
paused = false;}
void Timer::pause(){
if( ( started == true ) && ( paused == false ) ){
paused = true;
pausedTicks = SDL_GetTicks() - startTicks;}}
void Timer::unpause(){
if( paused == true ){
paused = false;
startTicks = SDL_GetTicks() - pausedTicks;
pausedTicks = 0;}}
int Timer::get_ticks(){
if( started == true ){
if( paused == true ){
return pausedTicks;}
else{return SDL_GetTicks() - startTicks;}
}return 0;}
bool Timer::is_started(){return started;}
bool Timer::is_paused(){return paused;}
int main( int argc, char* args[] ){
bool quit = false;
Square mySquare;
Timer fps;
if( init() == false ){return 1;}
if( load_files() == false ){return 1;}
wall.x = 130;
wall.y = 300;
wall.w = 220;
wall.h = 20;
while( quit == false ){
fps.start();
while( SDL_PollEvent( &event ) ){
mySquare.handle_input();
if( event.type == SDL_QUIT ){
quit = true;}}
mySquare.move();
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 1, 1, 1 ) );
SDL_FillRect( screen, &wall, SDL_MapRGB( screen->format, 237, 145, 33 ) );
mySquare.show();
if( SDL_Flip( screen ) == -1 ){return 1;}
if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ){
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );}}
clean_up();
return 0;}
最佳答案
您需要应用一些非常基础的物理知识。有可用的库,但对于像这样的简单案例,只需要最少的代码。
您已经有了 xVel 和 yVel 变量。当按下 UP 键时,框“跳”起来,您将值添加到 yVel。重力是影响箱子速度的恒定力。箱子加速向下。实际上,您在 move() 函数的每一帧中将重力应用于速度。
yVel -= GRAVITY; // Zero in space, small value on Moon, big value on Jupiter
box.y += yVel;
请注意,当盒子碰到地板时,您反转了 y 速度。这很好,但是在施加重力的情况下,重力会累积并且盒子最终会以荒谬的速度弹跳。盒子在弹跳时应该失去“能量”,例如,速度可能会减半。
您的代码中的问题是您使用的是整数值。重力是一种弱力,所以为了让它看起来真实,它应该是小值。对于整数值,可能无法找到该值。 (没有玩定点值,但这是另一个话题。)
因此考虑将 xVel 和 yVel 更改为 float 。当然,盒子的位置也应该使用 float 。
要获得更精确的物理学和考虑帧速率的真正精细的解决方案,请查看:https://gamedev.stackexchange.com/questions/15708/how-can-i-implement-gravity
关于C++ SDL 二维跳跃(重力),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14426870/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!