私はこれを800x600square持っています。私はスクリーンに描きたいです。私はその中の円を「カット」したいです(アルファは0になります)。基本的に私はこの四角形を地図上に描画していますので、描いたこれらの「円」では地図を見ることができます。そうでなければ灰色の四角形が表示されますSDL - 「ネガティブ」サークルを描く(霧の戦い)
答えて
だから、あなたは戦争の霧あなたの1人のゲーム?
私は数週間前にA *の探索を示すために地元の大学のために作った小さなデモを持っていたので、私はあなたに戦争の霧を加えることができると思った。ここでの結果です:
初期マップ
まず、あなたは完全なマップで始まり、完全に目に見える
霧
その後は、私はに表面を追加しました画面全体をカバーする(私の地図は画面よりも小さいので、この場合はscの戦争の霧を追加したREEN、しかし、あなたがスクロールしている場合、それは各マップの画素1をカバーしていることを確認してください。次に、あなたがそれを描画する必要があります1)
mFogOfWar = SDL_CreateRGBSurface(SDL_HWSURFACE, in_Width, in_Height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
SDL_Rect screenRect = {0, 0, in_Width, in_Height};
SDL_FillRect(mFogOfWar, &screenRect, 0xFF202020);
...私はゲームオブジェクトを描画した後やUIを描画する前にこの呼び出しを追加しましたが
void RenderingManager::DrawSurface(SDL_Surface* in_Surface, int in_X, int in_Y)
{
SDL_Rect Dest = { in_X, in_Y, 0, 0 };
SDL_BlitSurface(in_Surface, NULL, mScreen, &Dest);
}
あなたに次のような結果与えるべき
DrawSurface(mFogOfWar, 0, 0);
:
を私はこのようになります。その32ビット.png
を作成
"パンチ面"
(チェッカーボードがアルファを示して)
私のメインキャラクターをレンダリングするとき、私はこの呼び出しを追加:
gRenderingManager.RemoveFogOfWar(int(mX) + SPRITE_X_OFFSET, int(mY) + SPRITE_Y_OFFSET);
オフセット基本的にスプライトでパンチを中心にするには、RemoveFogOfWar
に渡すものが私のスプライトの中心です。
今
戦争の霧の肉戦争かぶりを削除します。私は、戦争の霧が永久に取り除かれ、戦争の霧がリセットされる2つのバージョンを行った。私の霧の戦いのリセットは私のpunch
表面に、アルファが0
にリセットされた輪郭と、輪郭よりも少ないピクセルのキャラクタがフレームごとに移動するという事実に頼っています。そうしないと、私のパンチが適用された場所はRect
です。私は新しいパンチを再び描く前にそれを補充するだろう。
SDLとの「乗算」ブレンドが見つかりませんでしたので、私はパンチ面を反復し、戦争面の霧のアルファを更新する簡単な関数を書くことにしました。
void RenderingManager::RemoveFogOfWar(int in_X, int in_Y)
{
const int halfWidth = mFogOfWarPunch->w/2;
const int halfHeight = mFogOfWarPunch->h/2;
SDL_Rect sourceRect = { 0, 0, mFogOfWarPunch->w, mFogOfWarPunch->h };
SDL_Rect destRect = { in_X - halfWidth, in_Y - halfHeight, mFogOfWarPunch->w, mFogOfWarPunch->h };
// Make sure our rects stays within bounds
if(destRect.x < 0)
{
sourceRect.x -= destRect.x; // remove the pixels outside of the surface
sourceRect.w -= sourceRect.x; // shrink to the surface, not to offset fog
destRect.x = 0;
destRect.w -= sourceRect.x; // shrink the width to stay within bounds
}
if(destRect.y < 0)
{
sourceRect.y -= destRect.y; // remove the pixels outside
sourceRect.h -= sourceRect.y; // shrink to the surface, not to offset fog
destRect.y = 0;
destRect.h -= sourceRect.y; // shrink the height to stay within bounds
}
int xDistanceFromEdge = (destRect.x + destRect.w) - mFogOfWar->w;
if(xDistanceFromEdge > 0) // we're busting
{
sourceRect.w -= xDistanceFromEdge;
destRect.w -= xDistanceFromEdge;
}
int yDistanceFromEdge = (destRect.y + destRect.h) - mFogOfWar->h;
if(yDistanceFromEdge > 0) // we're busting
{
sourceRect.h -= yDistanceFromEdge;
destRect.h -= yDistanceFromEdge;
}
SDL_LockSurface(mFogOfWar);
Uint32* destPixels = (Uint32*)mFogOfWar->pixels;
Uint32* srcPixels = (Uint32*)mFogOfWarPunch->pixels;
static bool keepFogRemoved = false;
for(int x = 0; x < destRect.w; ++x)
{
for(int y = 0; y < destRect.h; ++y)
{
Uint32* destPixel = destPixels + (y + destRect.y) * mFogOfWar->w + destRect.x + x;
Uint32* srcPixel = srcPixels + (y + sourceRect.y) * mFogOfWarPunch->w + sourceRect.x + x;
unsigned char* destAlpha = (unsigned char*)destPixel + 3; // fetch alpha channel
unsigned char* srcAlpha = (unsigned char*)srcPixel + 3; // fetch alpha channel
if(keepFogRemoved == true && *srcAlpha > 0)
{
continue; // skip this pixel
}
*destAlpha = *srcAlpha;
}
}
SDL_UnlockSurface(mFogOfWar);
}
:最も重要な部分は、それがコードの大部分を占めるので...そこにいくつかの作物の機能かもしれないが、私はチェックを気にしませんでした、あなたの表面の境界内にとどまることを確認することですその後、文字がkeepFogRemoved = true
そして、この周りを移動した後でさえkeepFogRemoved = false
で私にこれを与えました
検証
重要な部分は、あなたが外であなたのピクセルバッファの書き込み、その幅または高さのあなたをもたらす負のオフセットまたはオフセットと一緒に見ていないことを確認することが本当にあります。マウスをクリックすると、私は「オフずつ」問題
case SDL_MOUSEBUTTONDOWN:
{
if(Event.button.button == SDL_BUTTON_LEFT)
{
gRenderingManager.RemoveFogOfWar(Event.button.x, Event.button.y);
}
break;
}
ノートを持っていなかったことを確認するコーナーとエッジをしようとすると私のコードを検証するために、私はRemoveFogOfWar
に、単純な呼び出しを追加
明らかに、「パンチ」には32ビットのテクスチャは必要ありませんが、それを行う方法を示すために考えることができる最も明白な方法でした。これは1ピクセルあたりわずか1ビット(オン/オフ)を使用して行うことができます。戦争の
3州霧:あなたはまた、このようなスムーズなブレンドを保つために、いくつかのグラデーションを追加し、
if(*srcAlpha > *destAlpha)
{
continue;
}
のようなものに
if(keepFogRemoved == true && *srcAlpha > 0)
{
continue; // skip this pixel
}
を変更することができます
I私はこれを追加すべきだと思った...私は戦争の3つの状態の霧を作成する方法を追加:visible
、seen
とfogged
。
これを行うには、私は戦争のかぶりを最後に「打ち破った」場所のSDL_Rect
を保持し、アルファ値がある値よりも低い場合は、その値でクランプします。
だから、単に右戦争の霧は「パンチ」されたループの前に
for(int x = 0; x < mLastFogOfWarPunchPosition.w; ++x)
{
for(int y = 0; y < mLastFogOfWarPunchPosition.h; ++y)
{
Uint32* destPixel = destPixels + (y + mLastFogOfWarPunchPosition.y) * mFogOfWar->w + mLastFogOfWarPunchPosition.x + x;
unsigned char* destAlpha = (unsigned char*)destPixel + 3;
if(*destAlpha < 0x60)
{
*destAlpha = 0x60;
}
}
}
mLastFogOfWarPunchPosition = destRect;
を追加することによって、私はあなたがスタークラフトのようなゲームを持っている可能性が何に似て戦争の霧を取得します
戦争の「見えた」霧は半透明であるため、霧の中にある「敵」を適切にクリップするためにレンダリング方法を微調整する必要があります。まだ地形が見えます。
希望すると便利です。
- 1. デベロッパーエクスプレスレーダーチャートのサークルを描く
- 2. ビットマップAndroidで新しいサークルを描く
- 3. パイゲームでサークルを描くと白い点
- 4. パスを読んでサークルを描く
- 5. MapViewでサークル(半径)でオーバーレイを描く
- 6. スウィフト3でサークルを描く方法
- 7. プログラムでアンドロイドにサークルを描く
- 8. SDLでポリゴンを描く方法は?
- 9. ネガティブに続くCountDownTimer
- 10. MacOSアプリのSwiftでサークルを描くには?
- 11. アンドロイドでOpenGlを使ってサークルを描く方法は?
- 12. UrhoSharpでサークルまたはラインを描く方法
- 13. OpenTKは、私はC#でOpenGLとシンプルなサークルを描きたい透明サークル
- 14. Actionscript 3で基本的な "霧の戦争"効果を作り出すには?
- 15. OpenGL描画数千の2Dサークル
- 16. OpenGL/SDLを使った描画点
- 17. フラッシュの戦争効果の霧に関する効率的な問題
- 18. は霧
- 19. JavaScriptを使用してサークルを描く、スライバーのみを取得する
- 20. 標準デカルト円の数式を使ってグラフィックスモードでサークルを描く(C++)
- 21. Love2Dのサークル内でのみ描画するポリゴンを切り抜く
- 22. OpenLayersでGoogleマップでサークルを描画しない
- 23. Core Graphicsでサークルを描く - なぜこれは機能しませんか?
- 24. ゴム2(霧)とキーペアエラー
- 25. Android:基本的なサークルのアウトラインをRelativeLayoutに描画
- 26. なぜこのサークルはすべてのポイントを正しく描画しないのですか?
- 27. ネガティブ値へのハッシュ
- 28. 噴霧クラスフィールドの値は?
- 29. 画面にテキストを描く
- 30. 円の周りを動くサークル
円の画像をマップのアルファチャンネルに直接スタンプしたいですか? – Tommy
私は灰色のボックスを持っています。それから円が「消去」されているので、灰色のボックスが描画されているレイヤーに完全に透けて見えます。 – will