文档章节

移动的精灵,示例 SDL2 的图片分割、键盘消息

 四彩
发布于 2016/02/12 11:56
字数 795
阅读 98
收藏 2
点赞 1
评论 0

这是一个移动的精灵,用到了SDL2 的图片分割、键盘事件。

// spirit.c
// SDL2 移动的精灵

//#define _DEBUG_

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

// 图片文件
// 文件名
char *ImageFileName[] =
{
    "res/Town.jpg",     // 背景图文件
    "res/Fighter.png",  // Player文件
    "res/chick.png"     // NPC文件
};
// 图形属性:x = 横向分几幅,y = 纵向分几幅,w = 宽度,h = 高度
SDL_Rect ImageInfo[] =
{
    {1, 2, 640, 640},
    {4, 4, 128, 192},
    {4, 4, 128, 192}
};
// 图片的背景色
int BackColor = 0xFFFFFF;

// 字符串常量
char szWindowTitle[] = "SDL2 移动的精灵";

SDL_Texture *GetImageTexture(SDL_Renderer *pRenderer, char *FileName, _Bool bTransparent, int color);
void UpdateWindow(SDL_Window *pWindow, SDL_Renderer *pRenderer, SDL_Texture **pImageTexture,
                  int bx, int by, int px, int py, int nx, int ny, SDL_Rect *pd, SDL_Rect *nd);

#undef main
int main(int argc, char **argv)
{
    int nWindowWidth  = 640;        // 屏幕尺寸
    int nWindowHeight = 320;
    SDL_Window   *pWindow;          // 主窗口
    SDL_Renderer *pRenderer;        // 主窗口渲染器
    SDL_Texture  *pImageTexture[3]; // 棋盘背景、黑白棋子图纹理
    SDL_Event    event;     // 事件
    _Bool        bRun = 1;  // 持续等待事件控制循环标识

    // 背景、人物、NPC 的图幅坐标
    int bx = 0, by = 0, px = 0, py = 0, nx = 0, ny = 0;
    // 人物、NPC 的目标位置及大小
    SDL_Rect pr = {300, 300, 32, 48}, nr = {380, 230, 16, 24};
    // 移动速度
    int speed = 10;

    // 初始化:SDL2、SDL_Image(jpg)
    if(SDL_Init(SDL_INIT_VIDEO) == -1 || IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG) == -1)
    {
#ifdef _DEBUG_
        fprintf(stderr, "1 %s", SDL_GetError());
#endif
        return 1;
    }
    // 创建主窗口及其渲染器
    if(SDL_CreateWindowAndRenderer(640, 480, SDL_WINDOW_SHOWN, &pWindow, &pRenderer) == -1)
    {
#ifdef _DEBUG_
        fprintf(stderr, "2 %s", SDL_GetError());
#endif
        goto label_error;
    }
    SDL_SetWindowTitle(pWindow, szWindowTitle);
    // 加载图片文件
    if(NULL == (pImageTexture[0] = GetImageTexture(pRenderer, ImageFileName[0], 0, 0))
            || NULL == (pImageTexture[1] = GetImageTexture(pRenderer, ImageFileName[1], 1, BackColor))
            || NULL == (pImageTexture[2] = GetImageTexture(pRenderer, ImageFileName[2], 1, BackColor)))
    {
#ifdef _DEBUG_
        fprintf(stderr, "3 %s", IMG_GetError());
#endif
        goto label_error;
    }

    // 等待事件
    while(bRun && SDL_WaitEvent(&event))
    {
        switch(event.type)
        {
        case SDL_KEYDOWN :      // 键盘按键消息
            switch(event.key.keysym.sym)
            {
            case SDLK_RIGHT :
                py = 2;
                px++;
                pr.x = SDL_min(pr.x+speed, nWindowWidth-pr.w);
                break;

            case SDLK_LEFT :
                py = 1;
                px++;
                pr.x = SDL_max(pr.x-speed, 0);
                break;

            case SDLK_DOWN :
                py = 0;
                px++;
                pr.y = SDL_min(pr.y+speed, nWindowHeight-pr.h);
                break;

            case SDLK_UP :
                py = 3;
                px++;
                pr.y = SDL_max(pr.y-speed, 0);
                break;

            default :
                break;
            }
            px %= 4;
            UpdateWindow(pWindow, pRenderer, pImageTexture, bx, by, px, py, nx, ny, &pr, &nr);
            break;

        case SDL_WINDOWEVENT :      //  有窗口消息,重新计算窗口尺寸
            SDL_GetWindowSize(pWindow, &nWindowWidth, &nWindowHeight);
            UpdateWindow(pWindow, pRenderer, pImageTexture, bx, by, px, py, nx, ny, &pr, &nr);
            break;

        case SDL_QUIT :
            bRun = 0;
            break;

        default :
            break;
        }
    }

label_error:
// 清理
    if(pImageTexture[0] != NULL) SDL_DestroyTexture(pImageTexture[0]);
    if(pImageTexture[1] != NULL) SDL_DestroyTexture(pImageTexture[1]);
    if(pImageTexture[2] != NULL) SDL_DestroyTexture(pImageTexture[2]);
    IMG_Quit();
    SDL_Quit();
    return 0;
}

// 重绘窗口
void UpdateWindow(SDL_Window *pWindow, SDL_Renderer *pRenderer, SDL_Texture **pImageTexture,
                  int bx, int by, int px, int py, int nx, int ny, SDL_Rect *pr, SDL_Rect *nr)
{
    SDL_Rect srt;

    SDL_RenderClear(pRenderer);

    srt.x = bx*ImageInfo[0].w/ImageInfo[0].x;
    srt.y = by*ImageInfo[0].h/ImageInfo[0].y;
    srt.w = ImageInfo[0].w/ImageInfo[0].x;
    srt.h = ImageInfo[0].h/ImageInfo[0].y;
    SDL_RenderCopy(pRenderer, pImageTexture[0], &srt, NULL);

    srt.x = px*ImageInfo[1].w/ImageInfo[1].x;
    srt.y = py*ImageInfo[1].h/ImageInfo[1].y;
    srt.w = ImageInfo[1].w/ImageInfo[1].x;
    srt.h = ImageInfo[1].h/ImageInfo[1].y;
    SDL_RenderCopy(pRenderer, pImageTexture[1], &srt, pr);

    srt.x = nx*ImageInfo[2].w/ImageInfo[2].x;
    srt.y = ny*ImageInfo[2].h/ImageInfo[2].y;
    srt.w = ImageInfo[2].w/ImageInfo[2].x;
    srt.h = ImageInfo[2].h/ImageInfo[2].y;
    SDL_RenderCopy(pRenderer, pImageTexture[2], &srt, nr);

    SDL_RenderPresent(pRenderer);
}


// 取得图片文件纹理
// 参数:pRenderer = 渲染器;FileName = 图片文件名;bTransparent = 是否透明处理;color = 背景色
// 返回值:纹理指针
SDL_Texture *GetImageTexture(SDL_Renderer *pRenderer, char *FileName, _Bool bTransparent, int color)
{
    SDL_Texture *pTexture;
    SDL_Surface *pSurface;

    if((pSurface = IMG_Load(FileName)) == NULL)
        return NULL;
    if(bTransparent)
        SDL_SetColorKey(pSurface, 1, SDL_MapRGB(pSurface->format, color>>16, (color>>8)&0xFF, color&0xFF));
    pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
    SDL_FreeSurface(pSurface);

    return pTexture;
}

图片是从 C4droid  百度吧找来的。

人物移动位置没有进行合理性检查,这需要对地图进行分格定性。

© 著作权归作者所有

共有 人打赏支持
粉丝 25
博文 49
码字总数 77226
作品 0
茂名
html5游戏引擎phaser官方示例学习

phaser官方示例学习进行中,把官方示例调整为简明的目录结构,学习过程中加了点中文注释,代码在这里。 目前把官方的完整游戏示例看了一大半, breakout是敲砖块,gemmatch是钻石消除,invad...

祁达方 ⋅ 2015/11/27 ⋅ 0

Python编写微信打飞机小游戏(二)

  Python编写微信打飞机小游戏(一)   Python编写微信打飞机小游戏(二)   Python编写微信打飞机小游戏(三)   Python编写微信打飞机小游戏(四)   Python编写微信打飞机小游戏...

u013088062 ⋅ 2015/11/08 ⋅ 0

SDL2 自己画按钮

SDL2 没有自带控件,今天尝试自己画个按钮。 用图片按钮是最简单的:找几幅图片,代表不同的按钮状态,根据需要显示即可。 这里实现一个windows标准风格、文字的,可以通用,不用带着不同的图...

四彩 ⋅ 2016/02/14 ⋅ 0

我的开源视音频项目汇总

本文汇总一下自己视音频编解码学习方面的开源项目。这些开源项目大体上可以分成专业领域程序,FFmpeg示例程序,FFmpeg移植程序,多媒体项目示例程序,视音频编解码原理学习工程几个类别。这些...

leixiaohua1020 ⋅ 2015/01/13 ⋅ 0

将五子棋和时钟移植到安卓(C4droid)下,示例 SDL2 的夸平台移植、触摸事件

SDL2 跨越多种平台,那个五子棋很容易移至到 Android 上去,只需要调整下 Five.c 中的消息响应(把鼠标消息改成触摸消息),在调整下窗口风格为全屏即可。另外,安卓下SDL_mixer 支持 wav、o...

四彩 ⋅ 2016/02/14 ⋅ 0

疯狂ios讲义之cocos2d中的动画

cocos2d中的动画 在每一个游戏当中,都有很多各种各样的动画效果,比如街头霸王中的旋风腿,植物大战僵尸中豌豆的扭动、僵尸的走路、攻击动作等,虽然简单的移动动作也可以实现这些功能,但是...

博文视点 ⋅ 2014/04/15 ⋅ 0

用JSGF游戏框架开发支持HTML4的JS游戏!

JSDK是一个新发布的JS框架。在开源中国社区上的项目首页:http://www.oschina.net/p/jsdk 完整教程,请访问JSDK网站:http://jsdk2.sourceforge.net/ JSGF游戏开发课程(一):游戏开发原理与...

冯伯约 ⋅ 2012/04/12 ⋅ 6

C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(三十二) 雷、混、冰、毒、火、风 - 幻化中的魔法魅力!

魔法的魅力不仅仅因为其华丽的外表,更深层次的,它们的额外附加属性效果使得游戏世界更加幻化多彩!无论是中式的金木水火土5行,还是欧式的水火风雷,异或是日式的风林火山等等,在目前的网...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

[unity3d插件]2dtoolkit系列一 创建精灵

从今天开始要做一个2d游戏,由于之前都是做cocos2dx的,然后接触了一段时间的unity3d,都是做3D方面的东西,得知要做2d游戏还是有点开心的,或许因为不想丢失之前的2d游戏的一些思想,然后接...

丁小未 ⋅ 2014/03/04 ⋅ 0

[Unity3d插件]2dtoolkit系列一 创建精灵

从今天开始要做一个2d游戏,由于之前都是做cocos2dx的,然后接触了一段时间的unity3d,都是做3D方面的东西,得知要做2d游戏还是有点开心的,或许因为不想丢失之前的2d游戏的一些思想,然后接...

蓬莱仙羽 ⋅ 2014/03/04 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NFS介绍 NFS服务端安装配置 NFS配置选项

NFS介绍 NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netapp公司参与并主导...

lyy549745 ⋅ 16分钟前 ⋅ 0

Spring AOP 源码分析 - 筛选合适的通知器

1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析。本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出合适的通知器(Advisor...

java高级架构牛人 ⋅ 39分钟前 ⋅ 0

HTML-标签手册

标签 描述 <!--...--> 定义注释。 <!DOCTYPE> 定义文档类型。 <a> 定义锚。超链接 <abbr> 定义缩写。 <acronym> 定义只取首字母的缩写。 <address> 定义文档作者或拥有者的联系信息。 <apple......

ZHAO_JH ⋅ 40分钟前 ⋅ 0

SylixOS在t_main中使用硬浮点方法

问题描述 在某些使用场景中,应用程序不使用动态加载的方式执行,而是跟随BSP在 t_main 线程中启动,此时应用代码是跟随 BSP 进行编译的。由于 BSP 默认使用软浮点,所以会导致应用代码中的浮...

zhywxyy ⋅ 48分钟前 ⋅ 0

JsBridge原理分析

看了这个Github代码 https://github.com/lzyzsd/JsBridge,想起N年前比较火的Hybrid方案,想看看现在跨平台调用实现有什么新的实现方式。代码看下来之后发现确实有点独特之处,这里先把核心的...

Kingguary ⋅ 59分钟前 ⋅ 0

Intellij IDEA神器常用技巧五-真正常用快捷键(收藏级)

如果你觉得前面几篇博文太啰嗦,下面是博主多年使用Intellij IDEA真正常用快捷键,建议收藏!!! sout,System.out.println()快捷键 fori,for循环快捷键 psvm,main方法快捷键 Alt+Home,导...

Mkeeper ⋅ 59分钟前 ⋅ 0

Java 静态代码分析工具简要分析与使用

本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBugs,PMD,Jtest),最后从功能、特性等方面对它们进行分析和比较,...

Oo若离oO ⋅ 今天 ⋅ 0

SpringBoot自动配置小记

spring-boot项目的特色就在于它的自动配置,自动配置就是开箱即用的本源。 不过支持一个子项目的自动配置,往往比较复杂,无论是sping自己的项目,还是第三方的,都是如此。刚接触会有点乱乱...

大_于 ⋅ 今天 ⋅ 0

React jsx 中写更优雅、直观的条件运算符

在这篇文字中我学到了很多知识,同时结合工作中的一些经验也在思考一些东西。比如条件运算符 Conditional Operator condition ? expr_if_true : expr_if_false 在jsx中书写条件语句我们经常都...

开源中国最帅没有之一 ⋅ 今天 ⋅ 0

vim编辑模式与命令模式

5.5 进入编辑模式 从编辑模式返回一般模式“Esc” 5.6 vim命令模式 命令 :“nohl”=no high light 无高亮,取消内容中高亮标记 "x":保存退出,和wq的区别是,当进入一个文件未进行编辑时,使...

弓正 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部