zoukankan      html  css  js  c++  java
  • 游戏编程入门(1) -- 精灵 ISprite

        对于游戏编程而言,我也是个初学者,这个游戏编程入门系列的文章,就当作是我在学习游戏编程的笔记和阶段小结吧。我们先从最简单的“精灵”开始,暂时我们不需要考虑DirectX或是OpenGL,不需要考虑3维等等这些复杂情形,直接使用GDI+绘图功能就可以了。

        精灵,是构成游戏中活动体(比如,飞机、野兽等游戏人物)的最基本单元,任何一个活动体都可以由一个或多个精灵组合而成,每个精灵都是一个对象实例,它能够绘制自己、移动(更复杂的还可以旋转)等等基本动作。
        我让所有的精灵都实现ISprite接口,该接口如下:


        对应的代码如下:
        public interface ISprite
        {
            Graphics Graphics{
    set ;} //绘制的设备
            Bitmap   Source{set ;}   //精灵表面位图
            Image    BackgroundImage{set ;} //游戏背景

            Point Location{
    get ;}

            
    void Erase() ;
            
    void Draw() ;

            
    void SetDirection(CompassDirections dir) ;
            
    void Move() ;
        }

        
    public enum CompassDirections 
        {
            NotSet 
    = 0 ,
            North 
    = 1,
            NorthEast 
    = 2,
            East 
    = 3,
            SouthEast 
    = 4,
            South 
    = 5,
            SouthWest 
    = 6,
            West 
    = 7,
            NorthWest 
    = 8
        }

        这个接口也许并不是完整的,随了实际的深入,可能还会有很多的元素添加进来,甚至CompassDirections枚举还可以进一步细分,但是ISprite已经有最基本“精灵”功能了。对于大多数简单的任务,我们已经可以给出ISprite的一个实现:
        public class Sprite :ISprite
        {
            
    private CompassDirections direction = CompassDirections.South ;

            
    #region ISprite 成员
            
    private Graphics graphics = null ;
            
    public  Graphics Graphics
            {
                
    set
                {
                    
    this.graphics = value ;
                }
            }

            
    private Bitmap source = null ;
            
    public  Bitmap Source
            {
                
    set
                {
                    
    this.source = value ;
                }
            }

            
    private Point location = new Point(0 ,0) ;
            
    public  Point Location
            {
                
    get
                {
                    
    return this.location ;
                }
            }

            
    #region BackgroundImage
            
    private Image backgroundImage = null ; 
            
    public  Image BackgroundImage
            {
                
    set
                {
                    
    this.backgroundImage = value ;
                }
            }
            
    #endregion
            
            
    public void Erase()
            {
                Rectangle ret 
    = new Rectangle(this.location.X  , Location.Y, this.source.Width ,this.source.Height );
                
    this.graphics.DrawImage(this.backgroundImage, ret, ret, GraphicsUnit.Pixel);            
            }

            
    public void Draw()
            {
                
    this.graphics.DrawImage(this.source,this.location.X ,this.location.Y);
            }


            
    public void SetDirection(CompassDirections dir)
            {
                
    this.direction = dir ;
            }

            
    public void Move()
            {
                
    int stepSize = 5 ;
                
    if(this.direction == CompassDirections.South)
                {
                    
    this.location.Y += stepSize ;
                    
    return ;
                }

                
    if(this.direction == CompassDirections.East)
                {
                    
    this.location.X += stepSize ;
                    
    return ;
                }

                
    if(this.direction == CompassDirections.West)
                {
                    
    this.location.X -= stepSize ;
                    
    return ;
                }

                
    if(this.direction == CompassDirections.North)
                {
                    
    this.location.Y -= stepSize ;
                    
    return ;
                }
            }

            
    #endregion
        }

        我们要特别注意Erase方法的实现,所谓Erase实际上就是用背景图对应的区域重新绘制精灵所在的区域表面--这种技巧在游戏编程中是最基本的技巧之一。

        当精灵接收到游戏环境的时钟脉冲通知时,最常见的方法调用组合是:
                    theSprite.Erase() ;
                    theSprite.Move() ;
                    theSprite.Draw() ;
        首先,精灵擦除自己,然后依据方向CompassDirections移动自己到新的位置,最后在新的位置绘制自己。
        所以,当时钟脉冲连续不断的到来时,我们就可以看到精灵在移动了,通过我们的游戏操纵杆或键盘我们可以调用目标精灵的SetDirection方法来指定其要移动的方向。

        下篇文章,我们将基于ISprite构建一个最简单的游戏示例,在这个示例中,我们可以通过键盘的方向键来控制游戏中主角的移动。



  • 相关阅读:
    设计模式之设计原则
    浅谈简单工厂模式和策略模式
    Flask-SQLAlchemy插件
    SQLAlchemy的ORM
    Flask 微博三方登录
    SQLAlchemy介绍和基本使用
    Flask常用的钩子函数
    Flask-Restful详解
    flask信号使用
    多线程爬取斗图图片
  • 原文地址:https://www.cnblogs.com/zhuweisky/p/398520.html
Copyright © 2011-2022 走看看