Jian's profile星舞PhotosBlogListsMore Tools Help

Blog


    10/25/2008

    日子难过

    2个星期的时间里,2个考试3个大作业!考试不担心。。。但是作业都是挑战级难度的,按照平时的效率,平均要2个星期才能搞定1个,妈的。。。

    压力非常非常大,包括信心什么的都会有影响。。。哎。。。2个星期,不管结果如何,过程尽力就可以了!去年数据结构的最后一个作业是在交前2个小时才做的差不多的,而这学期,很可能会比去年要困难很多很多。。。

    在巨大的挑战面前,最好的应对方法就是无耻,再无耻点。。。我要绝对自大的认为在UOIT比我强的人还没有生出来-_-!!

    恩。。。压力一下子就全没了。。。

    10/24/2008

    OCT 24, 2008

          收到了一位好朋友寄来的明信片,雪山,古城,仙境般的地方。。。闭上眼,思绪跟上了她的脚步,仿如自己也悠闲的坐在石桥的栏杆上,游离于市井凡尘之外。这是一种享受,即使没有亲历,可也能感受到那干燥空气间夹杂着的迷幻般清雅的风正微微的拍打着我的脸。。。

          曾今很想去流浪

          披一件亚麻布的破旧风衣,缝隙间满是尘土;一条满是裂痕并脏兮兮的牛仔裤,远离城市的喧嚣,去感受别样的清馨风景。寻梦的旅途只能容下一人,甘愿成为一颗毫不起眼的小石子,融入自然的景色中,抑或化身成一粒在风中无拘无束的粉尘,把命运托付出去,然后就毅然的跟随着风的脚步。。。

          静下心来,发现,一切都是骚包

          流浪到余杭,既已饥寒交迫,无奈的依靠着街角的残旧土墙旁,捧着个黑乎乎,并已被地上的污水浸烂一角的馊馒头,哽咽而无法下咽。。。现实是很残酷的,如同一把利刃贯心而入,而还没回过神的时候,心脏既已停止跳动,全身的血液凝结在血管之中,恐惧的气氛也随着遍布全身的管络而蔓延开来,一切是诡异且静悄悄,精神,则早已从木讷转为呆滞了。

          曾想过逃跑,远离一切的压力

          锁住住所有的情感,眼神中只留下刚强和坚毅。但是,天下之大,又有何处能容身呢?想象着消失的感觉,那种瞬间粉末状的景象,皮肤迅速的分解,飘散,然后是肌肉,软组织。。。定格,打散,离散。。。微粒不断的分离,直至完全消隐在空气的呼吸声中。这样的消逝是唯美的,但唯美的,往往是不存在的。

          向往那片雪山,那片古镇,一切是那么的安逸

    (写于08年10月24夜,2门考试结束后)

    10/12/2008

    Oct.12

     
    认真接触MAYA已经毛1个星期了,在以后的时间里,尤其是在忙完期中后,我准备陆续放点作品上来。。。虽说学这个软件不能一步登天,但是我想直接从高级的建模开始,包括材质以及渲染,这很有挑战性,而且留给我的时间已经不多了!
     
    最近一直过着日夜颠倒的生活。。。要习惯这种转变,也要慢慢的压缩时间。。。张艺谋对我而言,没有什么印象深刻的,除了一句话:时间和乳沟一样,挤挤还是有的!
    10/10/2008

    品质决定一切

     

    但凡玩游戏的人,都认识暴雪公司;

    但凡知道暴雪公司的人,都知道这一句话:

    暴雪出品,必是精品!

    这无疑是对一个制作公司的最高荣誉,这个世界上,也只有这么一家企业享有这项殊荣。

    暴雪,在游戏领域,无疑是像神一样矗立着。。。这得益于它所属的创作团队,团队中的每个人,都是精英(虽然未必是最精英的人),但是对待游戏的态度却极其的严谨。一款游戏,如果有瑕疵的话,是绝对不会发行的!所以,暴雪的作品,只能慢慢等,1年,2年,5年,10年!但是,等作品真正拿出来的时候,所等待的时间绝对是值得的!

    另外一个在品质上能和暴雪有一拼的公司,则是日本的F社,既著名的FALCOM公司。

    旗下两大主要系列YS和英雄传说,都是在发行后不用再打补丁的!(除了垃圾娱乐通会发布些汉化修正补丁,以及免CD补丁)。和暴雪比起来,F社很穷,两个公司的资金状况绝对差了好几个层次,但是,在RPG玩家的心目中,F社的地位甚至超过暴雪!

    两个公司论技术,F社是儿科级,它最新的引擎技术用在英雄传说6空之轨迹FC、SC、RD和YS6、YS7、YS起源这6款游戏上,时间跨度有整整6年。。。而且ED7也可能会采用同样的引擎。。。真是把整套引擎给用到极致了。。。而且F社的引擎的粒子渲染能力,极其一般,这技术别说和quake3等世界顶级引擎比,就算是和一些国产的3D引擎比,可能都比不过,但是,通过这款引擎做出的游戏,却是完美的。。。超乎想象的完美!这一点,从那么多人等空轨RD的发售,就可见一斑!

    所以,一切都取决于品质!整套空之轨迹系列,我花了至少1000个小时,在这1000个小时中,只有一次因为卡在地图里,无法继续游戏(这个不是引擎的问题,而是那个位置确实是有问题),另外也就在窗口模式下,点游戏外的地方暂停游戏,再激活游戏后有可能出现无背景音乐,这么个不叫BUG的BUG,这就可见F社在做游戏的时候是何等的用心。。。反观国内,即使是代表RPG的巅峰之作,仙剑系列,也会有各种各样的BUG吧。。。

    国内的游戏公司,对品质是重视,但是当这个和经济效益冲突的时候,会毫不犹豫的下方品质至2线候命。。。暑假实习的公司的那款游戏,就是因为要赶时间完成,所以在有无数BUG的时候,竟毅然上线测试了。。。测试结果自然是惨不忍睹。。。囧。。。而公司的老板和我说,他不会等到游戏没有BUG了才去测试,那样的话,他会丢掉很多签合同的机会,至少,在那个时间上线,17173里网页游戏的排名,能蹿升至个很高的名次(确实,测试那会我看17173的排名,那款游戏在关注度上排到了第2)但是,这种不严谨的管理思路,坑害了购买这款游戏的联合运营商的利益,他们的结局,我想应该是苦涩的。。。

    当想真正投身这个行业的话,就绝对不能只盯着眼前的利益,这是每个做游戏的人应有的起码觉悟。要学习FALCOM,不一定要用最尖端的技术,但是却要在一切能力范围内,做到精益求精,这才是一个成长中的游戏企业应有的态度。

    10/7/2008

    最近有点焦头烂额

    一波作业轰炸,挺过去了。。。结果一看桌上挂的日历,貌似马上要期中了。。。明天有个课可能会有个quiz,结果我还没开始看书。。。哎。。。焦头烂额啊。。。
     
    怪物猎人2G也卡在轰龙那了。。。正好,先安心看书,熬过期中吧。。。
    10/4/2008

    XNA学习笔记1

    实现功能:载入图片,动画,键盘输入控制
     
    /* INFR 1350U Assignment One
     * Submit by: Jian Sun
     * Student ID No. 100285100*/
    using System;
    using System.Collections.Generic;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Net;
    using Microsoft.Xna.Framework.Storage;
    namespace Sun_as1
    {
        /// <summary>
        /// This is the main type for your game
        /// </summary>
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
            Texture2D spriteKarate;  //the main character
            Texture2D spriteNinjaStar; //the ninja star
            Rectangle karateRect;   //position information of the main character
            Rectangle ninjaStarRect; //position information of the ninja star
            public Game1()
            {
                graphics = new GraphicsDeviceManager(this);
                Content.RootDirectory = "Content";
            }
            /// <summary>
            /// Allows the game to perform any initialization it needs to before starting to run.
            /// This is where it can query for any required services and load any non-graphic
            /// related content.  Calling base.Initialize will enumerate through any components
            /// and initialize them as well.
            /// </summary>
            protected override void Initialize()
            {
                this.graphics.PreferredBackBufferHeight = 600; //set the display window's height equals 600
                this.graphics.PreferredBackBufferWidth = 800; //set the display window's wigth equals 800
                this.graphics.ApplyChanges();
     
                base.Initialize();
            }
            /// <summary>
            /// LoadContent will be called once per game and is the place to load
            /// all of your content.
            /// </summary>
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
                // Load two source pictures into this program
                spriteKarate = Content.Load<Texture2D>("sprite_karate_transp"); //load the picture, main character
                spriteNinjaStar = Content.Load<Texture2D>("sprite_ninjaStar"); //load the ninja star picture
                //setup the two source pictures' location
                karateRect = new Rectangle(0, graphics.GraphicsDevice.Viewport.Height / 2 - 133, 161, 266); //set position, in the middle of screen
                ninjaStarRect = new Rectangle(110, graphics.GraphicsDevice.Viewport.Height / 2 - 70, 50, 49); //set pisition of ninja star

            }
            /// <summary>
            /// UnloadContent will be called once per game and is the place to unload
            /// all content.
            /// </summary>
            protected override void UnloadContent()
            {
                // TODO: Unload any non ContentManager content here
            }
            /// <summary>
            /// Allows the game to run logic such as updating the world,
            /// checking for collisions, gathering input, and playing audio.
            /// </summary>
            /// <param name="gameTime">Provides a snapshot of timing values.</param>
            protected override void Update(GameTime gameTime)
            {
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
                // Allows the game to exit by pressing 'Q' and 'q' on keyborad
                KeyboardState keys;
                keys = Keyboard.GetState();
                if (keys.IsKeyDown(Keys.Q))
                    this.Exit(); //use a key 'Q' to exit
                //setup a speed of ninjastar
                int speed = 40;
                ninjaStarRect.X += speed;
                if (ninjaStarRect.X >= graphics.GraphicsDevice.Viewport.Width + 50) ninjaStarRect.X = 110; //while the star go outside the screen, the star will go to initial position
                base.Update(gameTime);
            }
            /// <summary>
            /// This is called when the game should draw itself.
            /// </summary>
            /// <param name="gameTime">Provides a snapshot of timing values.</param>
            protected override void Draw(GameTime gameTime)
            {
                graphics.GraphicsDevice.Clear(Color.WhiteSmoke); //change the background color to WhiteSmoke
                // draw these two source pictures in the window
                spriteBatch.Begin();
                spriteBatch.Draw(spriteKarate, karateRect, Color.White); //draw the main character
                spriteBatch.Draw(spriteNinjaStar, ninjaStarRect, Color.White); //draw the ninja star
                spriteBatch.End();

                base.Draw(gameTime);
            }
        }
    }
     
    代码相关图片资源:
    sprite_karate_transpsprite_ninjaStar
    10/3/2008

    openGL实现的2D人物移动、跳跃和攻击动画

    键盘W, J键控制人物跳跃, A键往左走,D键往右走,空格键攻击,S键原地不动

    如果用vector和sort()来管理每个源图片的ID,即可实现各个图片来回调用、切换的功能;在当前基础上,加进更多的逻辑判断,就能完成一个类似街机上超级玛丽类型的游戏。

    以下是代码:

    /******************************************/
    /* INFR 2310 - Assignment 1
    * Sprite Animation
    *
    * Part 1: Sprite Sheet Animation
    * Part 2: Sprite Movement
    * Part 3: Scrollers
    *
    * Author: Andrew Hogue
    * Date: September, 2008
    * Modified By: Sun, Jian/100285100
    *
    * Modification Description:Add a main character, background and foreground.
    * 'w'and 'j' could make the character jump; 'a' could make the character walk left, and 'd' could make the character walk right
    * 'space' could make the character attack; 's' could make the character stand
    *
    */
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <vector>
    #include <algorithm>
    #include <iostream>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include "GL/glut.h"
    #include "IL/il.h"
    #include "IL/ilu.h"
    #include "IL/ilut.h"
    /******************************************/
    /* GLOBAL VARIABLES */
    /******************************************/

    #define WINDOW_WIDTH 800
    #define WINDOW_HEIGHT 432

    /* anim types */
    enum {ANIM_ACTION=0, ANIM_JUMP,ANIM_WALK_LEFT,ANIM_WALK_RIGHT,ANIM_IDLE}; //I change the original enum

    /*********************************/
    /* GLOBAL SPRITE INFO */
    /*********************************/
    #define FRAMES_PER_SECOND_SPRITE 10
    const int FRAME_DELAY_SPRITE=1000/FRAMES_PER_SECOND_SPRITE;

    char *spriteSheetName      = "images/bleach_assignment1.gif";
    char *spriteBackgroundName = "images/newbackground.gif";
    char *spriteForegroundName = "images/newforeground.gif";

    /* no animation can have more than 100 frames */
    #define MAX_ANIM 100

    typedef struct _UVcoords_t
    {
       // a single (u,v) texture coordinate
        float u,v;
        int currentFrames;
    }UVcoords_t;

    typedef struct _spriteSheet_t
    {
        int width,height;
        unsigned int texId;
    }spriteSheet_t;

    typedef struct _spriteInfo_t
    {
        /* position info */
        float x,y;
       /* height of sprite in pixels on screen*/
        float width,height;
        // normalized width/height of sprite for texture
        float texWidth,texHeight;

        UVcoords_t anim[5]; //because I only have 5 anim in this assignment
        int currentAnimState;
        // the sprite comes from a sprite sheet
        spriteSheet_t sheet;
    }spriteInfo_t;

    static spriteInfo_t the_sprite;
    static spriteInfo_t background,foreground;

    /*********************************/
    /* function drawSprite()
    * Description:
    * - this function draws a 2D sprite at its internally defined location
    */
    void drawSprite(spriteInfo_t *s)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
        glPushMatrix();
        glTranslatef(s->x,s->y,0);

        /* you will need to change this */
        if (the_sprite.currentAnimState == ANIM_WALK_LEFT) //if the state is walk left
        {
            if(the_sprite.x<=400&&the_sprite.x>=10) //to make sure the main character will not out of the screen
                the_sprite.x--;
            background.anim[0].u -= 0.0005; //foreground move more fast than background
            foreground.anim[0].u -= 0.002;

        }
        if (the_sprite.currentAnimState == ANIM_WALK_RIGHT)
        {
            if(the_sprite.x<400)
                the_sprite.x++;
            background.anim[0].u += 0.0005;
            foreground.anim[0].u += 0.002;
        }

        int currentAnim = s->currentAnimState;
        int currentFrame = s->anim[currentAnim].currentFrames;
        UVcoords_t* UV = s->anim;
        float u = UV->u+s->texWidth*currentFrame; //change the frame of different anim
        float v = UV->v+s->texHeight*currentAnim;
        glColor3f(1,1,1);
           /* bind the appropriate texture frame */
            glBindTexture(GL_TEXTURE_2D,s->sheet.texId);
            /* draw the image as a quad the size of the first loaded image */
            glBegin(GL_QUADS);
                glTexCoord2f(u,v);
                glVertex3f(0,0,0);
                glTexCoord2f(u,v+s->texHeight);
                glVertex3f(0,s->height,0);
                glTexCoord2f(u+s->texWidth,v+s->texHeight);
                glVertex3f(s->width,s->height,0);
                glTexCoord2f(u+s->texWidth,v);
                glVertex3f(s->width,0,0);
            glEnd();
        glPopMatrix();
        glDisable(GL_BLEND);
        if (the_sprite.currentAnimState == ANIM_JUMP&&currentFrame == 7)
            the_sprite.currentAnimState = ANIM_IDLE; //this means the character can only jump once when 'j' or 'w' is pressed
        if (the_sprite.currentAnimState == ANIM_ACTION&&currentFrame == 7)
            the_sprite.currentAnimState = ANIM_IDLE; //this means the character can only attack once when 'space' is pressed
    }

    /* function DisplayCallbackFunction(void)
    * Description:
    *  - this is the openGL display routine
    *  - this draws the sprites appropriately
    */
    void DisplayCallbackFunction(void)
    {
       /* clear the screen */
        glClearColor(0,0.5,0,0);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();

       /* enable texturing */
        glEnable(GL_TEXTURE_2D);
        drawSprite(&background); //draw background first, and then the foreground, and finally the character
        drawSprite(&foreground);
        drawSprite(&the_sprite);

       /* display the drawn frame */
        glutSwapBuffers();
    }

    /* function void KeyboardCallbackFunction(unsigned char, int,int)
    * Description:
    *   - this handles keyboard input when a button is pressed
    */

    void KeyboardCallbackFunction(unsigned char key, int x, int y)
    {
        std::cout << "Keycode:"<<(int)key<<std::endl;
        switch(key)
        {
        case 32: // the space bar
            the_sprite.currentAnimState = ANIM_ACTION;
            break;
        case 27: // the escape key
        case 'q':
        case 'Q':
            exit(1);
            break;
        }
    }
    /* function void KeyboardUpCallbackFunction(unsigned char, int,int)
    * Description:
    *   - this handles keyboard input when a button is lifted
    */
    void KeyboardUpCallbackFunction(unsigned char key, int x, int y)
    {
        switch(key)
        {
        case 'w':
        case 'W':
        case 'j':
        case 'J':
            the_sprite.currentAnimState = ANIM_JUMP;
            break;
        case 'a':
        case 'A':
            the_sprite.currentAnimState = ANIM_WALK_LEFT;
            break;
        case 's':
        case 'S':
            the_sprite.currentAnimState = ANIM_IDLE; //I change the 's' to the state of idle
            break;
        case 'd':
        case 'D':
            the_sprite.currentAnimState = ANIM_WALK_RIGHT;
            break;
        }
    }

    /* function resetSprite()
    * Description:
    *  - reset's the sprite position
    */
    void resetSprite()
    {
        the_sprite.x = 90; //set the initial position of character
        the_sprite.y = 60;
        background.x = 0;
        foreground.x = 0;
    }
    /* function UpdateSpriteAnimation()
    * Description:
    *  - routine for moving sprite and updating animations
    */
    void UpdateSpriteAnimation()
    {
        int currentAnim = the_sprite.currentAnimState;
        the_sprite.anim[currentAnim].currentFrames = (the_sprite.anim[currentAnim].currentFrames++)%8;
    }

    /* function initSprite()
    * Description:
    *  - this initializes a sprite to default values
    */
    void initSprite(spriteInfo_t *s, int w, int h, char *name)
    {
        s->width  = w;
        s->height = h;
        s->sheet.texId  = ilutGLLoadImage(name);
        s->sheet.height = ilGetInteger(IL_IMAGE_HEIGHT);
        s->sheet.width  = ilGetInteger(IL_IMAGE_WIDTH);
        s->texHeight    = s->height/(float)s->sheet.height;
        s->texWidth     = s->width/(float)s->sheet.width;
        s->currentAnimState = ANIM_IDLE; //initializes the character's initial state
    }

    /* function loadSprite()
    * - this loads the character sprite
    */
    void loadSprite()
    {
        initSprite(&the_sprite, 193,193, spriteSheetName);
        initSprite(&background, 1280,432,spriteBackgroundName);
        initSprite(&foreground, 1014,432,spriteForegroundName);

       /* set up the initial position */
        resetSprite();
    }

    /* function initImageLibrary()
    * Description:
    *   - initialize the DevIL library properly
    */

    void initImageLibrary()
    {
        glEnable(GL_TEXTURE_2D);

        ilInit();
        iluInit();
        ilutRenderer(ILUT_OPENGL);

        loadSprite();
    }

    /* function TimerCallbackFunction(int value)
    * Description:
    *  - this is called many times per second
    *  - this enables you to animate things
    *  - no drawing, just changing the state
    *  - changes the frame number and calls for a redisplay
    *  - FRAME_DELAY_SPRITE is the number of milliseconds to wait before calling the timer again
    */
    void TimerCallbackFunction(int value)
    {
            UpdateSpriteAnimation();

            glutPostRedisplay();
            glutTimerFunc(FRAME_DELAY_SPRITE,TimerCallbackFunction,0);
    }

    /* function WindowReshapeCallbackFunction()
    * Description:
    *  - this is called whenever the window is resized
    *  - and sets up the projection matrix properly
    *  - currently set up for an orthographic view (2D only)
    */

    void WindowReshapeCallbackFunction(int w,int h)
    {
        float asp = (float)w/(float)h;
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0,w,0,h);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    }

    /* function main()
    * Description:
    *  - this is the main function
    *  - does initialization and then calls glutMainLoop() to start the event handler
    */
    int main(int argc, char **argv)
    {
        /* initialize the window and OpenGL properly */
        glutInit(&argc,argv);
        glutInitWindowSize(WINDOW_WIDTH,WINDOW_HEIGHT);
        glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
        glutCreateWindow("Sprite Anim, Modified By: Sun, Jian/100285100");//also add myself information on the screen

        /* set up our function callbacks */
        glutDisplayFunc(DisplayCallbackFunction);
        glutKeyboardFunc(KeyboardCallbackFunction);
        glutKeyboardUpFunc(KeyboardUpCallbackFunction);
        glutReshapeFunc(WindowReshapeCallbackFunction);
        glutTimerFunc(1,TimerCallbackFunction,0);

        /* enable texturing */
        glEnable(GL_TEXTURE_2D);
        /* initialize the image library engine */
        initImageLibrary();
       /* start the event handler */
        glutMainLoop();
        return 0;
    }

    以下是上面代码所使用的素材:

    bleach_assignment1newbackgroundnewforeground