第九章:加载背景
加载图片是游戏最基础的操作了。
我们先尝试加载一张图片,作为游戏背景显示出来。
这里我希望,游戏在不同分辨率下的手机,都可以看到一致的显示。并且显示尽可能最大化。
限定最小分辨率为 1024*768
if (g_SkyParkJni.getScreenWidth() < 1024
|| g_SkyParkJni.getScreenHeight() < 768) {
g_SkyparkLog.log("[%s][%d]Screen(%d*%d) < 1024*768", __FILE__, __LINE__,
g_SkyParkJni.getScreenWidth(), g_SkyParkJni.getScreenHeight());
exit(0);
}
创建一个坐标转换体系。用来实现窗口自适应大小
C:\data\www\SanguoSDL\jni\skypark_game\SkyparkChange.hpp
#ifndef SKYPARKCHANGE_HPP_
#define SKYPARKCHANGE_HPP_
namespace skypark {
class SkyparkChange {
public:
SkyparkChange() {
m_iBaseWidth = 1366;
m_iBaseHeight = 768;
m_iPositionX = 0;
m_iPositionY = 0;
m_bRatio = false;
m_iRatio = 1000;
}
void setWindowInfo(int iWidth, int iHeight) {
m_iScreenWidth = iWidth;
m_iScreenHeight = iHeight;
if (m_iBaseWidth == iWidth && iHeight >= m_iBaseHeight) {
m_iPositionY = (iHeight - m_iBaseHeight) / 2;
m_iWindowWidth = m_iBaseWidth;
m_iWindowHeight = m_iBaseHeight;
return;
}
int fw = (iWidth * 1000 / m_iBaseWidth);
int fh = (iHeight * 1000 / m_iBaseHeight);
if (fw > fh) {
fw = fh;
m_iPositionX = (iWidth - m_iBaseWidth * fw / 1000) / 2;
} else {
m_iPositionY = (iHeight - m_iBaseHeight * fw / 1000) / 2;
}
m_bRatio = true;
m_iRatio = fw;
m_iWindowWidth = m_iBaseWidth * fw / 1000;
m_iWindowHeight = m_iBaseHeight * fw / 1000;
}
public:
int m_iBaseWidth; //游戏面板
int m_iBaseHeight;
int m_iScreenWidth; //手机屏幕
int m_iScreenHeight;
int m_iWindowWidth; //游戏面板在手机屏幕中的大小
int m_iWindowHeight;
int m_iPositionX; //游戏面板在手机屏幕中的位置
int m_iPositionY;
bool m_bRatio; //是否有缩放比例
int m_iRatio; //缩放比例,千分之
};
}
#endif /* SKYPARKCHANGE_HPP_ */
下面的代码实现游戏背景加载:
C:\data\www\SanguoSDL\jni\src\SanguoMain.cpp
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <dirent.h>
#include <jni.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include "SDL_config.h"
#include "SDL_test.h"
#include "SDL.h"
#include "SDL_image.h"
#include "../skypark_game/skypark.h"
using namespace skypark;
//定义我的全局变量 --begin
static SDL_Window * g_screen_window = NULL;
static SDL_Renderer* g_screen_renderer = NULL;
static skypark::SkyparkLog g_SkyparkLog;
static skypark::SkyparkJni g_SkyparkJni;
static skypark::SkyparkChange g_SkyparkChange;
//定义我的全局变量 --end
//初始化
int skypark_sdl_init(char **argv) {
int iRet = SDL_Init(SDL_INIT_EVERYTHING);
if (iRet < 0) {
return -1;
}
g_screen_window = SDL_CreateWindow("skypark", 0, 0,
g_SkyparkJni.getScreenWidth(), g_SkyparkJni.getScreenHeight(),
SDL_WINDOW_FULLSCREEN);
if (g_screen_window == NULL) {
return -2;
}
g_screen_renderer = SDL_CreateRenderer(g_screen_window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (g_screen_renderer == NULL) {
return -3;
}
g_SkyparkJni.setScreen(g_screen_window, g_screen_renderer);
g_SkyparkChange.setWindowInfo(g_SkyparkJni.getScreenWidth(),
g_SkyparkJni.getScreenHeight());
return 0;
}
void ShowScreen(SDL_Texture * pSDL_Texture) {
sleep(1);
static Uint64 i = 0;
i++;
if (i % 10 == 0) {
g_SkyparkLog.log("[%s][%d]run...", __FILE__, __LINE__);
}
if (g_screen_renderer == NULL) {
return;
}
//设置颜色
SDL_SetRenderDrawColor(g_screen_renderer, 0x00, 0x00, 0x00, 0xFF);
//以上面的颜色擦除
SDL_RenderClear(g_screen_renderer);
//绘制背景
SDL_Rect stPos;
stPos.x = g_SkyparkChange.m_iPositionX;
stPos.y = g_SkyparkChange.m_iPositionY;
stPos.w = g_SkyparkChange.m_iWindowWidth;
stPos.h = g_SkyparkChange.m_iWindowHeight;
SDL_RenderCopy(g_screen_renderer, pSDL_Texture, NULL, &stPos);
//绘制一个矩形
SDL_Rect stRect;
stRect.w = 100;
stRect.h = 100;
stRect.x = 1024 - stRect.w;
stRect.y = 768 - stRect.h;
SDL_SetRenderDrawColor(g_screen_renderer, 0x00, 0x00, 0xFF, 0xFF);
SDL_RenderFillRect(g_screen_renderer, &stRect);
//将缓存刷新到实际屏幕
SDL_RenderPresent(g_screen_renderer);
}
#ifdef __cplusplus
extern "C" {
#endif
//jni接口 --begin
void Java_cn_skypark_sanguo_SanguoSDL_mySetAsset(JNIEnv* env, jclass tis,
jobject assetManager) {
AAssetManager * pAAssetManager = AAssetManager_fromJava(env, assetManager);
g_SkyparkJni.setAAssetManager(env, pAAssetManager);
}
//jni接口 --end
#ifdef __cplusplus
}
#endif
int main(int argc, char *argv[]) {
g_SkyparkLog.log("[%s][%d]begin w:%d h:%d f:%d", __FILE__, __LINE__,
Android_ScreenWidth, Android_ScreenHeight, Android_ScreenFormat);
int iRet = skypark_sdl_init(argv);
g_SkyparkLog.log("[%s][%d]skypark_sdl_init = %d", __FILE__, __LINE__, iRet);
if (g_SkyparkJni.getScreenWidth() < 1024
|| g_SkyparkJni.getScreenHeight() < 768) {
g_SkyparkLog.log("[%s][%d]Screen(%d*%d) < 1024*768", __FILE__, __LINE__,
g_SkyparkJni.getScreenWidth(), g_SkyparkJni.getScreenHeight());
exit(0);
}
//加载背景图片
SDL_Surface * pSDL_Surface = g_SkyparkJni.getPic("pic/bg.png");
if (pSDL_Surface == NULL) {
g_SkyparkLog.log("[%s][%d]pSDL_Surface = null", __FILE__, __LINE__);
exit(0);
}
g_SkyparkLog.log("[%s][%d]pic_w:%d pic_h:%d\n", __FILE__, __LINE__,
pSDL_Surface->w, pSDL_Surface->h);
SDL_Texture * pSDL_Texture = SDL_CreateTextureFromSurface(g_screen_renderer,
pSDL_Surface);
if (pSDL_Texture == NULL) {
g_SkyparkLog.log("[%s][%d]pSDL_Texture = null", __FILE__, __LINE__);
exit(0);
}
while (true) {
//sleep(60);
//g_SkyparkLog.log("[%s][%d]run...", __FILE__, __LINE__);
ShowScreen(pSDL_Texture);
}
g_SkyparkLog.log("[%s][%d]end", __FILE__, __LINE__);
return 0;
}
真机测试如下:
附上项目代码:
http://download.csdn.net/detail/ycg01/6792211