3D Game Programming 2D game Ming-Te Chi Department of Computer Science, National Chengchi University 2018
Outline 2D game history Coordinate system Simple 2D game example 介紹如何由OpenGL製作2D小遊戲
2D Video Game History
The first video game Tennis for Two was a game developed in 1958 on an analog computer, which simulates a game of tennis or ping pong on an oscilloscope. The Original Video Game http://www.youtube.com/watch?v=6PG2mdU_i8k
2D GAME PONG 1972. earliest video game Arcade Original Pong http://www.youtube.com/watch?v=LPkUvfL8T1I
Snake (1970s) Control a snake to move, and avoid hitting to wall or its growing tail.
Galaxian (1979 by Namco) 小蜜蜂類型的遊戲, 可以看到隨顯示器和硬體的進步,遊戲玩法和畫面的變化, 右邊是當初的海報,可看出其故事性: 迎擊外星侵略者
Basic elements Elements Tetrads Jesse Schell Aesthetics Mechanics Story Jesse Schell 提出遊戲的組成可以四個的角度去解析。 這四個角度包含機制、技術、故事和美術,每一個向度有其對立和相輔相成的部份。 Technology
Mechanics Story Aesthetics Technology the procedures and rules the sequence of events that unfolds in your game Aesthetics how your game looks, sounds, tastes, and feels. Technology any materials and interactions that make your game possible
Pac Man 1980 by Namco http://www.google.com/pacman/ google用java script寫的pacman
Game & Watch 1980 Game & Watch is a line of handheld electronic games produced by Nintendo from 1980 to 1991. CM http://www.youtube.com/watch?v=oq64s8TmANM Ball: the first game & watch game
Family Computer(FAMICOM) Mario series. By Nintendo Family Computer(美國: NES)系統限制 48彩色和6灰色的調色盤, 64個sprite以及單一的捲軸 標準解析度256x240 pixel (for NTSC 256x224) Mario Bros. 1983 Super Mario Bros. 1985 Donkey Kong 1981
Tetris Design by 阿列克謝·帕基特諾夫 Puzzle game (Алексей Леонидович Пажитнов)in 1984 Puzzle game 俄羅斯方塊為益智遊戲的代表之一
Super Mario World. 1990 Rich color, Parallax scrolling, zoom and rotate sprite. 硬體的進步,使得能使用的顏色更多,角色數更多 帶來遊戲的畫面和玩法進步
Doom 1993 A landmark 1993 first-person shooter (FPS)video game by id Software. Video games with 2.5D graphics 透過圖片的縮放去模擬出透視的效果,一般歸類到2.5D遊戲
3D Graphics – early stage
3D Graphics http://www.epicgames.com/ http://www.youtube.com/watch?v=Ky-JUL0SDDs littlebig planet 2
Social game Happy Farm 社群網路的興起,使遊戲可與朋友產生互動,增加遊戲的玩法 http://www.playfish.com/ http://www.zynga.com/ Happy Farm
Mobile phone Angry Birds by Rovio flight control by Firemint Muliti-touch game in mobile device 觸控界面帶來直覺的玩法, 如flight control 畫出降落的規跡引導飛機的降落 像Angry Birds使用手指直接決定彈弓的角度和力度 Angry Birds by Rovio flight control by Firemint
LBS & AR
Snake in 2014 Nimble Quest Trailer 2013 March https://www.youtube.com/watch?v=n-QMoe0jzQ8
2D Video Game History
Cartesian Plane +y (4, 3) (0, 0) +x (-3, -2) +z 對於物體位置,採用迪卡爾座標系統描述,以垂直正交的座標軸定義出每個頂點所在的座標位置(x, y) +z
Coordinate Clipping +y (150, 100) (75, 50) (0, 0) +x (-75, -50) 對於3D空間的可視範圍,我們可以定義出所謂的Clipping空間,如紅色虛線框出的立方體 繪圖硬體可根據clipping空間,略過空間外的不可見的物件,用來加速
Super Mario Bros. Nintendo Game world Super Mario Bros. Nintendo
Viewport Mapping drawing coordinates to windows coordinates +y (0, 0) Viewport則是在螢幕(或視窗的顯示範圍),設定一塊區域,與clipping space做對應 OpenGL中可以指定多個viewport轉換,使同一個視窗畫面呈現不同角度或不同場景的畫面 (0, 0) +x clipping space Window space
Projection Getting 3D to 2D Orthographic projections Perspective projections 投影則是將3D物體從world space投影轉換到image space的過程,常用的有正交投影和透視投影 這幾個名詞,還會在05-Transformation和06-Projection做詳細的介紹
Representing Visuals 3D objects Lighting Shader Mesh: geometry Materials Texture maps Lighting Shader
2D game
What is a Game? – Elliot Avedon and Brian Sutton-Smith Games are an exercise of voluntary control systems, in which there is a contest between powers, confined by rules in order to produce a disequilibrial outcome. – Elliot Avedon and Brian Sutton-Smith 遊戲心理學家Brian Sutton-Smith
Game architecture Asset Management Game Loop I/O System loading saving caching Start() Update(delta) Display(delta) Keyboard, mouse audio storage 遊戲的架構 遊戲事件的迴圈: 在初始化後,每一個畫格(時間間隔),更新物間的狀態之後,再將之繪製在畫面上 輸入輸出系統: 管理玩家的輸入,畫面聲音的輸出 資產(asset)管理: 遊戲物件(3D模型、聲音檔)的資源管理
A simple example A character has three states: stand, walk, and jump Use “A” and “D”key to move the character When press “j”, the character will jump, and the score will increase by 1. 簡單的遊戲 -單一角色有三個狀態:站立、走路和跳 -利用左或右鍵的輸入移動角色 -按下j 角色會跳躍,並且會增加score變數1
State Position, direction, Gamesocre Jump Press “j” to trigger jump() 先決定角色的狀態,以及對應不同輸入產生的狀態變化 Stand Walk Press “A” or “D”
Debug & moving // Use this for initialization void Start () { Debug.Log("Hello, start!!"); } // Update is called once per frame void Update () { this.transform.position += new Vector3(1, 0, 0); }
Control speed float speed = 20; // Use this for initialization void Start () { Debug.Log("Hello, start!!"); } // Update is called once per frame void Update () { this.transform.position += new Vector3(speed*Time.deltaTime, 0, 0); }
waking void Update () { if (Input.GetKey(KeyCode.D)) { this.transform.position += new Vector3(speed*Time.deltaTime, 0, 0); } }
jump float dis = speed * Time.deltaTime; if (JumpCount >= 0) { if(JumpCount < 20) { this.transform.position += new Vector3(0, dis, 0); } else { this.transform.position += new Vector3(0, -dis, 0); } JumpCount++; if (JumpCount>39) { IsJump = false; JumpCount = -1; } } bool IsJump = false; int JumpCount = -1; void Update () { if(Input.GetKey(KeyCode.Space)) { if(!IsJump) { IsJump = true; JumpCount = 0; } } …. }
Sprite switch public Sprite[] sprites; int sprites_index = 0; // Update is called once per frame void Update () { if (Input.GetKey(KeyCode.D)) { this.transform.position += new Vector3(speed * Time.deltaTime, 0, 0); int i = (++sprites_index)%2; this.GetComponent<SpriteRenderer>().sprite = sprites[i]; } }
Art challenges technology; technology inspires the art. - John Lasseter John Lasseter 曾是pixar這家動畫公司的首席創意長,主要是負責美術和動畫創意 Pixar是創作出玩具總動員等長篇電腦動畫的公司,這pixar他們嘗試結合工程技術和藝術創造 在他的觀察下,發現,往往工程師熟知技術的極限,因此創造力會較為受限,但是藝術家的創意往往可以挑戰工程上的可能性 另外工程上的突破,也往往激發出藝術上的交流 遊戲的製作往往也如此,由於是跨領域的合作,往往可以激蕩出更多的火花
OpenGL 2D
class RGBApixmap RGBApixmap pic; pic.readBMPFile(“stand.bmp”); pic.setChromaKey(232, 248, 248); // draw pic.blendtex(picX, picY, 1.0, 1.0); RGBpixmap.h in lab2 //alternative draw glPixelZoom(1.0, 1.0); glWindowPos2i(picX, picY); pic.blend();
State and Image Jump 設定對應的影像 Stand Walk
State int whichpPic;
Change State void display() { … if (DirectState==0) { //向右 void SpecialKeys(int key, int x, int y) { switch(key) { case GLUT_KEY_LEFT: picX -= 5; if (whichPic==0) whichPic=1; else whichPic=0; DirectState=1; //left break; case GLUT_KEY_RIGHT: picX += 5; DirectState=0; //right } void display() { … if (DirectState==0) { //向右 pic[whichPic].blendTex(picX, picY, 1, 1); } else { //向左 int offset = pic[whichPic].nCols; //圖的寬度 pic[whichPic].blendTex(picX+offset, picY, -1, 1); //調整x位置,並以x=0為軸翻轉影像 } }
Font rendering //Font char mss[30]; sprintf(mss, "Score %d", Gamescore); glColor3f(1.0, 0.0, 0.0); //set font color glRasterPos2i(10, 550); //set font start position void * font = GLUT_BITMAP_9_BY_15; for(int i=0; i<strlen(mss); i++) { glutBitmapCharacter(font, mss[i]); } 這段程式碼 可將Gamescore變數所儲存的分數資訊,以bitmap的方式繪在 (10, 550)的位置 需放在display()內
Press J to Trigger jump() void myKeys(unsigned char key, int x, int y) { switch(key) case ‘J': case ‘j': if(jumpState==0) { jumpState=1; Gamescore++; jump(0); } break; glutPostRedisplay(); 透過鍵盤的輸入 按下j 產生對應的動作,並更新Gamescore的變數 這樣可以實作出加分的機制
Jump motion void jump(int i) { whichPic=2; //switch state if(i<=10) { if (i<5) picY+=4; else picY-=4; i++; glutTimerFunc( 100, jump, i); }else { whichPic=0; jumpState=0; } glutPostRedisplay(); picY 5 i Jump 是我們設定的TimerFunction 藉此更新角色的位置PicY 並呼叫glutPostRedisplay(); 更新畫面