ZEngine Demo 9 - ZImage 中级 图形特效处理



easycker
2010-11-10 22:18:27

[i=s] 本帖最后由 easycker 于 2010-11-12 15:58 编辑 [/i]

首先,欢迎各位步入了ZEngine的中级开发阶段

大家用了这么久的ZEngine,发现ZEngine 的优势没?
速度~效率,开发的容易度~~

[b]各种类的使用我给大家总结下方法[/b]:
1.在Game.h的Game类中声明ZEngine类的对象,比如ZImage,ZAudio等等的对象(ZImage *m_imgName等)
2.在GameInitial()中初始化对象并加载(m_imgName = new ZImage();等)以及其他变量初始化(如m_x=10等)GameInitial中的所有代码只执行1遍,
可以做开场动画
3.在GameCircle()中做数据的变化处理(如图片的坐标m_x +=10)等。这个函数中的代码循环执行
4.在GameDrawScene()绘制图形,比如Show函数和ZPaint的绘图函数必须放在这里 。这里也可以处理数据的变化,可做GameCircle()中可做的内容,
这里的代码也是循环执行
5.GameButtonDown()和GameButtonUp()中按键处理
6.GameEnd()这里做指针的释放,内存的清理等工作(delete m_imgName等),也可以不清理(psp退出时会自动释放所有游戏内存)。
也可以做游戏结束时的动画,这里的代码只执行一遍。



[b]ZImage类使用流程总结[/b]:
1.Game.h的Game类中创建 对象 (ZImage *m_img);
2.GameInitial中初始化和Load资源
3.GameDrawScene中 Show图片



一、[b]图形移动,色彩遮罩,缩放,旋转。 这个例子可是做多功能的 图片游览器或者图片编辑器的 基础[/b]
基本实现了图片移动,旋转,缩放,颜色遮罩等的特效,其中也用到了状态机,希望大家好好理解下
以下是代码,大家可以按照序号来做[code]按键操作说明:
//上下左右移动图片
//设置色彩遮罩 select + cross/circle等 组合键来设置 色彩+变化
//设置色彩遮罩 start + cross/circle等 组合键来设置 色彩-变化
//L R翻转图片
//square和cross分别控制 宽度和高度 - ,triangle和circle分别控制 宽度和高度 +
//同时按下start和select 复原图片状态[/code][code]//Game.h
#ifndef _GAME_H
#define _GAME_H

#include "ZGame.h"

class Game : public ZGame
{
public:
Game(){}
~Game(){}

void GameInitial();
void GameCircle();
void GameDrawScene();
void GameButtonDown(int nKeyNumber);
void GameButtonUp(int nKeyNumber);
void GameEnd();

public:
//(2)
struct s_ZImage //建立处理ZImage显示用的结构体
{
float x,y; //图形左上角坐标
float wn,hn; //源图像长宽的n倍
float angle; //图片角度
int r,g,b,a; //遮罩色彩的红,绿,蓝,透明度四个通道
};

enum e_KEY
{
K_UP = 0,K_DOWN,K_LEFT,K_RIGHT,
K_CROSS,K_CIRCLE,K_SQUARE,K_TRIANGLE,
K_L,K_R,
K_SELECT,K_START
};

void f_m_img_s_init(); //自定义的初始化m_img_s结构初始化的函数
private:
//(1)
ZImage *m_img; //图像对象
s_ZImage m_img_s; //图像结构变量
int m_img_state[12]; //建立12个按键的状态,按下为1,弹起为0
float m_img_speed; //设定移动等变量变化的速度
};

#endif[/code][code]
//Game.cpp
//游戏入口类

#include "Game.h"

//游戏初始化
void Game::GameInitial()
{
//(3)img初始化
m_img = new ZImage();

//结构
f_m_img_s_init(); //调用自定义的m_img_s初始化函数

int i;
for(i=0;i<12;i++)
m_img_state[i] = 0; //全部状态清零

m_img_speed = 3; //速度为3

//(4)img加载
m_img->Load("image/demo0.jpg");
}


//游戏循环
void Game::GameCircle()
{
//(8)处理状态,也用if...if....处理,因为各个功能相互独立

//上下左右移动图片
if(m_img_state[K_UP]) //当状态不为零则执行
{
m_img_s.y -= m_img_speed;
if(m_img_s.y + (float)m_img->GetImageP()->h < 0)
m_img_s.y = -(float)m_img->GetImageP()->h;
}
if(m_img_state[K_DOWN])
{
m_img_s.y += m_img_speed;
if(m_img_s.y - (float)m_img->GetImageP()->h > 0)
m_img_s.y = (float)m_img->GetImageP()->h;
}
if(m_img_state[K_LEFT])
{
m_img_s.x -= m_img_speed;
if(m_img_s.x + (float)m_img->GetImageP()->w < 0) //当图片最右边到了屏幕最左边
m_img_s.x = -(float)m_img->GetImageP()->w; //限制不要超过了
}
if(m_img_state[K_RIGHT])
{
m_img_s.x += m_img_speed;
if(m_img_s.x - (float)m_img->GetImageP()->w > 0)
m_img_s.x = (float)m_img->GetImageP()->w;
}

//设置色彩遮罩 select + cross/circle等 组合键来设置 色彩+变化
if(m_img_state[K_SQUARE] &&
m_img_state[K_SELECT]) //红色
{
m_img_s.r += (int)m_img_speed;
if(m_img_s.r > 255) //限制范围
m_img_s.r = 255;
}
if(m_img_state[K_CROSS] &&
m_img_state[K_SELECT]) //绿色
{
m_img_s.g += (int)m_img_speed;
if(m_img_s.g > 255) //限制范围
m_img_s.g = 255;
}
if(m_img_state[K_CIRCLE] &&
m_img_state[K_SELECT]) //蓝色
{
m_img_s.b += (int)m_img_speed;
if(m_img_s.b > 255) //限制范围
m_img_s.b = 255;
}
if(m_img_state[K_TRIANGLE] &&
m_img_state[K_SELECT]) //透明度
{
m_img_s.a += (int)m_img_speed;
if(m_img_s.a > 255) //限制范围
m_img_s.a = 255;
}


//设置色彩遮罩 start + cross/circle等 组合键来设置 色彩-变化
if(m_img_state[K_SQUARE] &&
m_img_state[K_START]) //红色
{
m_img_s.r -= (int)m_img_speed;
if(m_img_s.r < 0) //限制范围
m_img_s.r = 0;
}
if(m_img_state[K_CROSS] &&
m_img_state[K_START]) //绿色
{
m_img_s.g -= (int)m_img_speed;
if(m_img_s.g < 0) //限制范围
m_img_s.g = 0;
}
if(m_img_state[K_CIRCLE] &&
m_img_state[K_START]) //蓝色
{
m_img_s.b -= (int)m_img_speed;
if(m_img_s.b < 0) //限制范围
m_img_s.b = 0;
}
if(m_img_state[K_TRIANGLE] &&
m_img_state[K_START]) //透明度
{
m_img_s.a -= (int)m_img_speed;
if(m_img_s.a < 0) //限制范围
m_img_s.a = 0;
}

//L R翻转图片
if(m_img_state[K_L])
{
m_img_s.angle += m_img_speed; //加m_img_s.angle += 90; 为常用的90°翻转,
}
if(m_img_state[K_R])
{
m_img_s.angle -= m_img_speed;
}

//square和cross分别控制 宽度和高度 - ,triangle和circle分别控制 宽度和高度 +
if(m_img_state[K_SQUARE] && //按square
!m_img_state[K_SELECT] && //没有按下select
!m_img_state[K_START]) //没有按下start
{
m_img_s.wn -= (float)(m_img_speed * 0.01);
}
if(m_img_state[K_CROSS] && //按square
!m_img_state[K_SELECT] && //没有按下select
!m_img_state[K_START]) //没有按下start
{
m_img_s.hn -= (float)(m_img_speed * 0.01);
}
if(m_img_state[K_TRIANGLE] && //按square
!m_img_state[K_SELECT] && //没有按下select
!m_img_state[K_START]) //没有按下start
{
m_img_s.wn += (float)(m_img_speed * 0.01);
}
if(m_img_state[K_CIRCLE] && //按square
!m_img_state[K_SELECT] && //没有按下select
!m_img_state[K_START]) //没有按下start
{
m_img_s.hn += (float)(m_img_speed * 0.01);
}

//同时按下start和select 复原图片状态
if(m_img_state[K_SELECT] &&
m_img_state[K_START])
{
f_m_img_s_init(); //调用自定义的m_img_s初始化函数
}
}

//游戏绘图
void Game::GameDrawScene()
{
//(5)
m_img->Show(0,0,(float)m_img->GetImageP()->w,(float)m_img->GetImageP()->h, //保持图片完整显示
m_img_s.x, m_img_s.y, m_img_s.wn, m_img_s.hn, m_img_s.angle, //显示用到结构中的数据
ZImage::RGBA(m_img_s.r, m_img_s.g, m_img_s.b, m_img_s.a));
}

//按下按键
void Game::GameButtonDown(int nKeyNumber)
{
//(6)用if...if...因为可以同时按下
if(nKeyNumber == PSP_BUTTON_UP) m_img_state[K_UP] = 1; //按上键状态K_UP(0)置位,一下相同
if(nKeyNumber == PSP_BUTTON_DOWN) m_img_state[K_DOWN] = 1;
if(nKeyNumber == PSP_BUTTON_LEFT) m_img_state[K_LEFT] = 1;
if(nKeyNumber == PSP_BUTTON_RIGHT) m_img_state[K_RIGHT] = 1;
if(nKeyNumber == PSP_BUTTON_CROSS) m_img_state[K_CROSS] = 1;
if(nKeyNumber == PSP_BUTTON_CIRCLE) m_img_state[K_CIRCLE] = 1;
if(nKeyNumber == PSP_BUTTON_SQUARE) m_img_state[K_SQUARE] = 1;
if(nKeyNumber == PSP_BUTTON_TRIANGLE) m_img_state[K_TRIANGLE] = 1;
if(nKeyNumber == PSP_BUTTON_LEFT_TRIGGER) m_img_state[K_L] = 1;
if(nKeyNumber == PSP_BUTTON_RIGHT_TRIGGER) m_img_state[K_R] = 1;
if(nKeyNumber == PSP_BUTTON_SELECT) m_img_state[K_SELECT] = 1;
if(nKeyNumber == PSP_BUTTON_START) m_img_state[K_START] = 1;

}

//弹起按键
void Game::GameButtonUp(int nKeyNumber)
{
//(7)用if...if... 按键弹起时清零相应位
if(nKeyNumber == PSP_BUTTON_UP) m_img_state[K_UP] = 0; //按上键状态K_UP(0)置位,一下相同
if(nKeyNumber == PSP_BUTTON_DOWN) m_img_state[K_DOWN] = 0;
if(nKeyNumber == PSP_BUTTON_LEFT) m_img_state[K_LEFT] = 0;
if(nKeyNumber == PSP_BUTTON_RIGHT) m_img_state[K_RIGHT] = 0;
if(nKeyNumber == PSP_BUTTON_CROSS) m_img_state[K_CROSS] = 0;
if(nKeyNumber == PSP_BUTTON_CIRCLE) m_img_state[K_CIRCLE] = 0;
if(nKeyNumber == PSP_BUTTON_SQUARE) m_img_state[K_SQUARE] = 0;
if(nKeyNumber == PSP_BUTTON_TRIANGLE) m_img_state[K_TRIANGLE] = 0;
if(nKeyNumber == PSP_BUTTON_LEFT_TRIGGER) m_img_state[K_L] = 0;
if(nKeyNumber == PSP_BUTTON_RIGHT_TRIGGER) m_img_state[K_R] = 0;
if(nKeyNumber == PSP_BUTTON_SELECT) m_img_state[K_SELECT] = 0;
if(nKeyNumber == PSP_BUTTON_START) m_img_state[K_START] = 0;
}

//游戏结束
void Game::GameEnd()
{
Quit();
}



//////////////////////////////////////////////////////////////////////////
//用户自定义函数区
//////////////////////////////////////////////////////////////////////////

//(3)同时写这个
void Game::f_m_img_s_init()
{
m_img_s.angle = 0;
m_img_s.hn = 1; //1倍,原始大小
m_img_s.wn = 1;
m_img_s.x = 0;
m_img_s.y = 0;
m_img_s.r = 255; //无遮罩效果
m_img_s.g = 255;
m_img_s.b = 255;
m_img_s.a = 255;
}
[/code]请大家思考,能否将这个做的和IPHONE那样平滑的 转动呢?
提示:设置m_img_speed的变化


boy545003571
2010-11-10 23:03:15

唷,都到中级篇了,继续收藏


easycker
2010-11-11 17:21:20

因为太大了所以没人下载嘛?
当你用了以后你会发现你下载了还是非常非常值得的。