質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

908閲覧

SDL2でのキー入力で画像が動かない

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/05/30 01:02

編集2019/05/30 01:31

前提・実現したいこと

SDL2の勉強をしているものです。
こちらのサイトを参考にキー入力で画像を動かせるプログラムを作っていたのですが、キー入力をしても画像が動きません。
サイト自体がSDL2のものではないので、SDL2で同じ動作をするAPIに対応させていますがそこで間違っているのかもしれません。
escを押した際にはきちんとプログラムが停止します。
今回、実現したいことは画像の移動なので背景の塗りつぶしは省いています。

該当のソースコード

c=

1#include "SDL2/SDL.h" 2#include "SDL2/SDL_image.h" 3#include <stdio.h> 4 5int main(int argc, const char *argv[]) 6{ 7 SDL_Rect rect, scr_rect, rect_tmp; 8 SDL_Window *Window; 9 SDL_Surface *image, *Screen; 10 11 SDL_Init(SDL_INIT_EVERYTHING); 12 SDL_Event event; 13 int isFinish = 0; 14 15 Window = SDL_CreateWindow("InsertKey", 0, 0, 640, 640, SDL_WINDOW_INPUT_FOCUS); 16 17 image = IMG_Load("red_round.png"); 18 19 Screen = SDL_GetWindowSurface(Window); 20 21 rect.x = 0; 22 rect.y = 0; 23 rect.w = image->w; 24 rect.h = image->h; 25 26 scr_rect.x = 0; 27 scr_rect.y = 0; 28 29 SDL_BlitSurface(image,&rect,Screen,&scr_rect); 30 31 rect_tmp = scr_rect; 32 33 SDL_UpdateWindowSurface(Window); 34 35 while (isFinish == 0) 36 { 37 while (SDL_PollEvent(&event)) 38 { 39 switch (event.type) 40 { 41 case SDL_KEYDOWN: 42 switch (event.key.keysym.sym) 43 { 44 case SDLK_UP: 45 rect_tmp.y -= rect.h; 46 break; 47 48 case SDLK_DOWN: 49 rect_tmp.y += rect.h; 50 break; 51 52 case SDLK_RIGHT: 53 rect_tmp.x += rect.w; 54 break; 55 56 case SDLK_LEFT: 57 rect_tmp.x -= rect.w; 58 break; 59 60 case SDLK_ESCAPE: 61 isFinish = 1; 62 63 default: 64 break; 65 } 66 } 67 } 68 69 SDL_Delay(1); 70 } 71 72 SDL_DestroyWindow(Window); 73 SDL_Quit(); 74 75 return 0; 76} 77

試したこと

SDL2ではSDL_GetVideoSurfaceがないため、対応するものを調べてみましたがそれらしいものが見つかりませんでした。

補足情報(FW/ツールのバージョンなど)

gcc /Users/prg/Key.c -lSDL2 -lSDL2_Image -g -o0 -o a.outでコンパイルしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ループ内で一度も画面の更新を行っていないので、
SDL_BlitSurfaceSDL_UpdateWindowSurfaceをループ内に書けばOKのはずですが、
SDL2ではSDL_GetWindowSurfaceではなくSDL_CreateRendererを使います。

理由については以下のサイトに日本語訳がありますが、
SDL 1.2から2.0への移行

要約すると、従来のサーフェスを使ったやり方は主にシステムメモリとCPUを使用
新しいレンダラーを使ったやり方はビデオRAMとGPUを使用しハードウェアアクセラレーションで行われる。
といった感じです。

なので、SDL1じゃなくてちゃんとSDL2の解説をしているサイトを見ませう。

Beginning Game Programming v2.0

cpp

1#include <SDL.h> 2 3int main(int argc, char *argv[]) 4{ 5 SDL_Init(SDL_INIT_VIDEO); 6 7 auto window = SDL_CreateWindow(u8"インサートキー", SDL_WINDOWPOS_UNDEFINED, 8 SDL_WINDOWPOS_UNDEFINED, 640, 640, 9 SDL_WINDOW_SHOWN); 10 11 auto renderer = SDL_CreateRenderer(window, -1, 0); 12 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); 13 14 auto image = SDL_LoadBMP("red_round.bmp"); 15 auto texture = SDL_CreateTextureFromSurface(renderer, image); 16 SDL_Rect rect = {0, 0, image->w, image->h}; 17 SDL_FreeSurface(image); 18 19 auto isFinish = false; 20 SDL_Event event; 21 22 while (isFinish == false) 23 { 24 while (SDL_PollEvent(&event)) 25 { 26 switch (event.type) 27 { 28 case SDL_KEYDOWN: 29 switch (event.key.keysym.sym) 30 { 31 case SDLK_UP: 32 rect.y -= rect.h; 33 break; 34 case SDLK_DOWN: 35 rect.y += rect.h; 36 break; 37 case SDLK_LEFT: 38 rect.x -= rect.w; 39 break; 40 case SDLK_RIGHT: 41 rect.x += rect.w; 42 break; 43 44 case SDLK_ESCAPE: 45 isFinish = true; 46 break; 47 default: 48 break; 49 } 50 break; 51 case SDL_QUIT: 52 isFinish = true; 53 break; 54 default: 55 break; 56 } 57 } 58 // ここで、画面のクリア・描画処理・画面への反映を行う 59 SDL_RenderClear(renderer); 60 SDL_RenderCopy(renderer, texture, nullptr, &rect); 61 SDL_RenderPresent(renderer); 62 } 63 64 SDL_DestroyTexture(texture); 65 SDL_DestroyRenderer(renderer); 66 SDL_DestroyWindow(window); 67 68 SDL_Quit(); 69 70 return EXIT_SUCCESS; 71} 72

投稿2019/05/30 08:50

編集2019/05/30 08:59
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/05/31 03:37

回答ありがとうございます。 ご提示いただいたコードをC言語用に書き換えてコンパイルしたら無事動きました。 ここで質問なのですが、`SDL_Texture`と`SDL_Renderer`と`SDL_Surface`の違いがいまいちわかりません。 前の二つに関しては、中身がどうなっているのか調べてもよくわかりませんでした。構造体の中に関数が入っているという認識で間違い無いでしょうか?
退会済みユーザー

退会済みユーザー

2019/05/31 07:51

本文にも少し触れてると思うんだけども…、 SDL_Surface: メインメモリに画像データを格納してソフトウェアでレンダリング(処理は主にCPUが処理を行う) ピクセルデータがメモリにそのまま格納されているので、直接内部にアクセスして色を変えたりとかフィルターを掛けたりとか内容を変更することが出来る。 SDL_Texture: 画像データをテクスチャー(ポリゴンの表面に貼るアレです)としてVRAMに格納 内部的にはOpenGL(Windowsの場合はデフォルトはDirect3D)を使用していて3Dで処理しハードウェアアクセラレーションが効く(GPUが処理を負担する) VRAMには直接アクセス出来ないので、内部データを後から書き換えは出来ない。 ハードウェアで処理するので高速 SDL_Renderer: これを説明しろって言われても困るんだけども… (内部的に)3Dとして扱われているデータを色々処理を施して画面に表示できる形に処理をする所?
退会済みユーザー

退会済みユーザー

2019/05/31 08:21

なるほど!ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問