Animation(動畫) 靜宜大學資工系 蔡奇偉 副教授 2006-2007.

Slides:



Advertisements
Similar presentations
计算机动画与仿真. 计算机动画是计算机图形学和艺术相结合 的产物,它是伴随着计算机硬件和图形算 法高速发展起来的一门高新技术,它综合 利用计算机科学、艺术、数学、物理学和 其它相关学科的知识在计算机上生成绚丽 多彩的连续的虚拟真实画面,给人们提供 了一个充分展示个人想象力和艺术才能的 新天地。 计算机动画是计算机图形学和艺术相结合.
Advertisements

单元二:面向对象程序设计 任务二:借书卡程序设计.
JAVA 编 程 技 术 主编 贾振华 2010年1月.
项目7 面向对象高级.
四資二甲 第三週作業 物件導向程式設計.
Memory Pool ACM Yanqing Peng.
项目:贪吃蛇游戏设计 工作任务一:系统设计(system design) 工作任务二:豆类(Bean)设计
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
第五章 树 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
雷 霆 战 机 By—谷恩轩&余万全.
项目:贪吃蛇游戏设计 工作任务三:块类(Block)设计 工作任务四:蛇类(Snake)设计
第二章 JAVA语言基础.
類別與物件 Class & Object.
C++程序设计 王希 图书馆三楼办公室.
AOP实践 演讲人:陈思荣.
OOSDL 靜宜大學資工系 蔡奇偉 副教授
内容提要 对象的生命周期 构造函数 析构函数 拷贝构造函数. 常宝宝 北京大学计算机科学与技术系
4.1 概述 4.2 类与对象的实现 4.3 对象的初始化和析构 4.4 类的包含 4.5 类模板
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
Screen Layout & Background Image
Ch13 集合與泛型 物件導向程式設計(2).
第七章 搜索结构 静态搜索结构 二叉搜索树 AVL树.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
第六章 继承性和派生类 胡昊 南京大学计算机系软件所.
程式設計實作.
類別樣板 Class Template 類似函式樣板 由類別樣板產生的類別稱為類別樣版的實體(instance)
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
程式撰寫流程.
第4章 物件導向分析與設計簡介 4-1 物件導向的軟體系統開發 4-2 物件導向分析與設計 4-3 UML的物件導向分析與設計
王豐緒 銘傳大學資訊工程學系 問題:JAVA 物件檔輸出入.
2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 2D圖形與字型的呈現.
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
可降阶的高阶方程 一、 型的微分方程 二、不显含未知函数的方程 三、不显含自变量的方程.
C/C++/Java 哪些值不是头等程序对象
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
$10 可空类型.
Chapter12 Graphs Definitions Applications Properties
C#程序设计基础 第二章 数据类型.
10 多載函數 10.1 多載概論 多載一般函數 多載成員函數 10-3
第三章 C# 基础知识.
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C++复习2----类与对象.
第三章 数据抽象.
第5章 文本与字体 2019/4/25 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2019/4/25 Huang Weitong.
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
第二章 Java语法基础.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
本节内容 对象拷贝 视频提供:昆山爱达人信息技术有限公司.
本节内容 引用类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第 9 章 建構函式與解構函式.
目标 流程控制 字符串处理 C# 的类和对象 C# 访问修饰符 C# 构造函数和析构函数.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
挑戰C++程式語言 ──第9章 函數.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
硬幣遊戲解題詳解 王豐緒 銘傳大學資訊工程學系.
第2章 Java语言基础.
Chapter 2 Entity-Relationship Model
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
判斷(選擇性敘述) if if else else if 條件運算子.
本节内容 在堆中创建对象 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二章 Java基础语法 北京传智播客教育
Presentation transcript:

Animation(動畫) 靜宜大學資工系 蔡奇偉 副教授 2006-2007

內容大綱 簡介 Motion Animation Sprite Animation

簡介 動畫是由隨時間而改變的圖片所產生 2D 遊戲動畫可由下列三種技巧產生: Motion Animation Sprite Animation Motion + Sprite Animation

Motion Animation 遊戲角色的位置隨時間而變。 玩家控制角色移動 自主性移動:遊戲角色按照既定路徑而移動, 不受外界因素的干擾(碰撞除外)。 被動性移動:遊戲角色的移動受到其他角色的 牽引,如追逐與逃脫。 如何設定移動路徑?

移動路徑 直線路徑 速率 (velocity) = 單位時間的位移向量 (dx, dy) 速度 (speed) = 單位時間的位移長度 = | (dx, dy) | 距離 (distance) = 速度  時間

多線段路徑 計算簡單 足夠密的多線段可以用來模擬曲線路徑

曲線路徑 explicit formula: 簡單曲線如二次錐線 parametric formula: 複雜曲線或 Bezier curves 足夠密的多線段

CPolylinePath private: CPoint *m_vertices; // 端點序列 int *m_durations; // 時間序列(單位 frame) int m_maxsize; // 序列最大長度 int m_size; // 序列使用長度 int m_index; // 目前線段的索引 CPoint m_startVertex; // 目前線段的起點 int dx, dy; // 目前線段的向量 CPoint m_currentPos; // 目前位置 int m_dfCount; // duration frame count int m_currentDur // current duration bool m_bCycle; // 是否循環

bool CPolylinePath::Alloc (int size) { m_vertices = new CPoint[size]; m_durations = new int[size-1]; if (m_vertices && m_durations) m_maxsize = size; m_size = 0; m_index = 0; return true; } else if (m_vertices) { delete [] m_vertices; m_vertices = NULL; if (m_durations) { delete [] m_durations; m_durations = NULL; m_maxsize = 0; return false;

CPolylinePath::CPolylinePath (int size) { Alloc(size); } CPolylinePath::CPolylinePath (CPoint *vertices, int *durations, int size, bool bCycle=false) if (Alloc(size)) Setup(vertices, durations, size, bCycle) CPolylinePath::~CPolylinePath () delete [] m_vertices; delete [] m_durations; CPolylinePath::OK () return m_size != 0;

bool CPolylinePath::Setup (CPoint *vertices, int *durations, int size, bool bCycle=false) { if (size > m_maxsize || size < 2) return false; int k; for (k = 0; k < size-1; k++) m_vertices[k] = vertices[k]; m_durations[k] = durations[k]; if (durations[k] <= 0) } m_size = size; m_bCycle = bCycle; EnterSegment(0) return true;

void CPolylinePath::GetCurretnPosition (CPoint &pos) { pos = m_currentPos; } bool CPolylinePath::IsStopped () return (m_index == m_size-2 && m_dfCount == m_currentDur && !m_bCycle); void CPolylinePath::EnterSegment (int n) m_index = n; m_startVertex = m_vertices[n]; dx = m_vertices[n+1].x - m_startVertex.x; dy = m_vertices[n+1].y - m_startVertex.y; m_currentPos = m_startVertex; m_currentDur = m_durations[n]; m_dfCount = 0;

bool CPolylinePath::NextPosition (CPoint &pos) { if (IsStopped()) { pos = m_currentPos; return false; } m_dfCount++; if (m_dfCount == m_currentDur) if (m_index < m_size -2) EnterSegment(m_index+1); else if (m_index == m_size -2) if (m_bCycle) EnterSegment(0); else m_currentPos = m_vertices[m_size -1]; else { m_currentPos.x = m_startVertex.x + m_dfCount*dx/m_currentDur; m_currentPos.y = m_startVertex.y + m_dfCount*dy/m_currentDur; return true;

CPolylineMotionObject 類別 class CPolylineMotionObject { public: CPolylineMotionObject() : m_path(0){} bool LoadImage (char *file) return m_image.LoadImage(file); } // 其他成員函式 private: CSurface m_image; CPolylinePath *m_path; };

bool CPolylineMotionObject::SetupPath ( CPoint *vertices, int *durations, int size, bool bCycle=false) { m_path = new CPolylinePath(vertices, durations, size, bCycle); if (m_path && m_path.OK()) return true; else delete m_path; return false; }

CPolylineMotionObject::FirstShow () { CPoint pos; m_path->GetCurretnPosition(pos); m_image.Show(pos); } CPolylineMotionObject::NextShow () m_path->NextPosition(pos);

class CMyGameApp : public CGameApp { public: CMyGameApp () : CGameApp() {} protected: virtual bool InitializeApp (); virtual bool AppMain (); private: CPolylineMotionObject m_ballObj; };

bool CMyGameApp::InitializeApp () { CPoint vertices[5]; int durations[4] = {50, 100, 50, 100}; vertices[0].Set(50, 50); vertices[1].Set(50, 400); vertices[2].Set(550, 400); vertices[3].Set(550, 50); vertices[4].Set(50, 50); m_ballObj.LoadImage ("ball.png"); m_ballObj.SetupPath(vertices, durations, 5, true); m_pScreen->Clear(); m_ballObj.FirstShow(); return true; }

bool CMyGameApp::AppMain () { m_pScreen->Clear(); m_ballObj.NextShow(); return true; } int main ( int argc, char* argv[] ) CMyGameApp myGameApp; myGameApp.InitializeSDL(); myGameApp.SetScreen(); myGameApp.SetCaption(WINDOW_TITLE); myGameApp.Run(); return EXIT_SUCCESS;

Sprite Animation Sprite 是什麼? Sprite Set Surface Play List Sprite Animation Implementation

Sprite 是什麼? Sprite 是遊戲畫面上會改變形狀的物件。 參見網站 http://www.videogamesprites.net/

Sprite Set Surface 為了減少繪圖頁的數量,我們通常把相關的 sprite 圖形擺在一張繪圖頁上,如下圖所示:

CSpriteSet 類別 class CSpriteSet : public CSurface { public: CSpriteSet () : CSurface() {} void Setup (char *file, int n, int m, CRect *pRects = NULL, bool bDisplayFormat = true); bool ShowSprite (int k, Sint16 x, Sint16 y); int SpriteWidth (int k); int SpriteHeight (int k); void GetSpriteRect (int k, CRect &rect); private: int m_numSprites; CRect *m_spriteRects; };

bool CSpriteSet::Setup (char *file, int n, int m, CRect *pRects, bool bDisplayFormat) { if (!LoadImage(file, bDisplayFormat)) return false; int count = n*m; m_spriteRects = new CRect[count]; if (m_spriteRects == NULL) int k; if (pRects) for (int k = 0; k < count; k++) m_spriteRects[k] = pRects[k]; else int w = Width() / m; int h = Height() / n; int i, j, x, y = 0; k = 0; for (i = 0; i < n; y+=h, i++) for (j = 0, x = 0; j < m; x+=w, j++) m_spriteRects[k++].Set(x, y, w, h); } return true;

bool CSpriteSet::ShowSprite (int k, Sint16 x, Sint16 y) { Show(m_spriteRects[k], x, y); } int CSpriteSet::SpriteWidth (int k) return m_spriteRects[k].w; int CSpriteSet::SpriteHeight (int k) return m_spriteRects[k].h; void CSpriteSet::GetSpriteRect (int k, CRect &rect) rect = m_spriteRects[k];

CPlayList 類別 class CPlayList { public: CPlayList(CSpriteSet *pSpriteSet); void Setup (int *sequence, int n, int delay = 1); bool ShowSprite (int k, Sint16 x, Sint16 y); bool Play (Sint16 x, Sint16 y); private: CSpriteSet *m_pSpriteSet; int m_numFrames; int *m_sequence; int m_currentFrame; int m_delay; int m_delayCount; bool m_bCycle; };

bool CPlayList::Setup (int *sequence, int n, int delay, bool bCycle) { if (n < 1) return false; if (m_sequence) delete [] m_sequence; m_sequence = new int[n]; if (!m_sequence) m_numFrames = n; for (int i = 0; i < n; i++) m_sequence[i] = sequence[i]; m_delay = delay; m_bCycle = bCycle; m_currentFrame = 0; m_delayCount = m_delay; return true; }

bool CPlayList::ShowSprite (int k, Sint16 x, Sint16 y) { return m_pSpriteSet->ShowSprite(m_sequence[k], x, y); } bool CPlayList::Play (Sint16 x, Sint16 y) bool bEnd = false; m_delayCount--; if (m_delayCount == 0) if (m_currentFrame == m_numFrames-1) { if (m_bCycle) m_currentFrame = 0; else bEnd = true; m_currentFrame++; m_delayCount = m_delay; ShowSprite (m_currentFrame, x, y); return bEnd;

class CMyGameApp : public CGameApp { public: CMyGameApp () : CGameApp() {} protected: virtual bool InitializeApp (); virtual bool AppMain (); private: CSpriteSet m_spriteset; CPlayList *m_pPlayList; };

bool CMyGameApp::InitializeApp () { int seq[] = {0, 1, 2}; m_spriteset.Setup("mariobros.png", 1, 3); m_spriteset.SetColorKey(0, 0, 0); m_pPlayList = new CPlayList(&m_spriteset); m_pPlayList->Setup(seq, 3, 5); return true; }

bool CMyGameApp::AppMain () { m_pScreen->Clear(); m_pPlayList->Play(200, 200); return true; } int main( int argc, char* argv[] ) CMyGameApp myGameApp; myGameApp.InitializeSDL(); myGameApp.SetScreen(); myGameApp.SetCaption(WINDOW_TITLE); myGameApp.Run(); return EXIT_SUCCESS;