XNA教程(二)—— Into the 2D World

2024-01-19 00:32
文章标签 教程 world 2d xna

本文主要是介绍XNA教程(二)—— Into the 2D World,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  作者:Mike Fleishauer & clayman
本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
Blog:
http://blog.csdn.net/soilwork
clayman_joe@yahoo.com.cn 
special thanks to Mike Fleishauer ^_^

        在第一章里,我们介绍了关于 XNA 的一些基础知识。但坦白的说,至今为止,我们还没有编写任何代码,而且只创建了一个单调的蓝色屏幕。
         这一章,我们将尝试在屏幕上绘制一些东西,简单的 2D 图形。虽然 2D 游戏的时代已经渐渐远去,但即使你编写一个全 3D 的游戏,也不得不处理处理一些 2D 图形,比如简单的选项菜单、 HUD head up displays )等等。好了让我们开始把。
         打开上一章创建的项目,当然,你也可以创建一个新 XNA 项目。把解决方案改名为“ Chapter2”,把工程和Game1.cs 都重命名为“ Sprite ”,当弹出确认更改文件名的对话框时,点击确认。
         接下来,我们将在屏幕上绘制一张 2D 图片。但在这之前,需要介绍一点关于 Sprite 的概念。
什么是 Sprite
Sprite ,也称为精灵,是一个直接绘制到屏幕上的 2D 图形。在传统的 2D 游戏中,你所看到的一切几乎都是 sprite 。但在 3D 游戏中,比如 Halo sprite 逐渐演变为了用于增加 3D 图形视觉效果的纹理。在讨论 3D 图形时我们会详细讲解它。现在,简单的把 sprite 认为是 2D 图形就可以了。
        
         继续,我们将把一些外部资源添加到工程中,为了方便管理,统一把资源放到一个单独的文件夹中。在 Solution Explorer 邮件点击 Add->New Floder ,命名为 Graphics 。接下来,邮件点击新创建的文件夹 Add->Existion Item…. 在弹出窗口中,导航到安装 MC2 源代码的目录下,在 /Source/Data/Art 中,选择 mcl_splashscreen_planet_2.tga. 文件。(当然,可以选择一张任何你喜欢的图片)。
         接下来,编写代码:
namespace Chapter2
{
    partial class Sprites : Microsoft.Xna.Framework.Game
    {
        private Microsoft.Xna.Framework.Graphics.SpriteBatch _sb;
        private Microsoft.Xna.Framework.Graphics.Texture2D _sprite;
        public Sprites()
        {
            InitializeComponent();
            _sb = new SpriteBatch(this.graphics.GraphicsDevice);
            _sprite = Texture2D.FromFile(this.graphics.GraphicsDevice, "../../Graphics/mcl_splashscreen_planet_2.tga");
        }
        protected override void Update()
        {
            float elapsed = (float)ElapsedTime.TotalSeconds;
            UpdateComponents();
        }
        protected override void Draw()
        {
              if (!graphics.EnsureDevice())
                return;
            graphics.GraphicsDevice.Clear(Color.Black);
            graphics.GraphicsDevice.BeginScene();
            _sb.Begin();
            _sb.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.Red);
            _sb.End();
            DrawComponents();
            graphics.GraphicsDevice.EndScene();
            graphics.GraphicsDevice.Present();
        }
    }
}
(加粗部分为我们添加的代码)
         这些代码是什么意思呢?
         首先,我们为 Sprite 类添加了两个全新的成员:
private Microsoft.Xna.Framework.Graphics.SpriteBatch _sb;
private Microsoft.Xna.Framework.Graphics.Texture2D _sprite;
     _sb 是一个SpriteBatch对象。SpriteBatch对象代表了一批sprite,并且将在同样的状态设置下,绘制他们。大多数情况下,几乎所有的sprite都在同一个批次中。
     _sprite 实际上是一张2D的纹理。它代表了一张将要绘制到屏幕上的图片。我们稍后将讨论不同类型的纹理,现在,只需知道2D纹理储存了在X和Y方向上,每个像素的颜色信息。也可以就把Texture2D认为是一张图片。XNA直接支持jpg,tga,dds,bmp,png格式的文件作为纹理。
_sb = new SpriteBatch(this.graphics.GraphicsDevice);
     使用GraphicsDevice对象作为参数,实例化SpriteBatch。这里,参数的含义表示以后将用哪一个(一个程序中可以有多个GraphicsDevice)GraphicsDevice对象绘制_sb。
_sprite = Texture2D.FromFile(this.graphics.GraphicsDevice, "../../Graphics/mcl_splashscreen_planet_2.tga");
         这行代码把图片加载到内存中,实例化 Texture2D 对象。同样把当前的 graphics device 和图片的路径作为参数。如果在给定路径没有找到所要的图片,那么这个方法将抛出一个异常。
graphics.GraphicsDevice.Clear(Color.Black);
         把屏幕清理为黑色。上一节已经介绍过如何使用这个方法。现在我会告诉你为什么需要调用这个方法。如果把渲染比作绘图,那么显存就是我们的画板,通常把用于绘图的显存称为帧缓冲,如何不清理帧缓冲,那么上次在帧缓冲中绘制的图形仍然会保留在其中,并且这些数据处于一种不确定的状态。假设我们下次只在屏幕的左上角绘制图形,那么显示时,除了进行绘制的区域,其他部分可能会显示一些随机数据,相当于我们在一块绘制了大量图形的旧画板上绘图。因此,需要用 Clear 方法对帧缓冲进行初始化,填充为某个我们希望的背景颜色。
_sb.Begin();
_sb.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.Red);
_sb.End();        
         和之前提到的 BeginScenne EndScene 一样, _sb.Begin _sb.End 方法告诉图形设备我们将要绘制 sprite ,所有绘制 sprite 的代码都必须在这两个方法之间。 Draw 方法是真正绘制图形的地方。这里的参数告诉显卡从坐标位置为( 0 0 )的地方开始绘制 sprite 。注意,绘制 sprite 的,所使用的是屏幕坐标系,这意味着屏幕中的每个像素对应一个( x y , 屏幕左上角的坐标总是( 0 0 ),而右下的坐标则取决于屏幕分辨率,如果分辨率为 1024 x 768 那么右下的坐标就是( 1024 768 )。绘制 sprite 的位置应该在这两个坐标之间。
         运行程序看看吧:

         虽然依旧很单调,但总是有了进步。
         这里你可能会有一些问题:为什么原来蓝色的天空,现在“燃烧”了起来。
         注意看绘制 sprite 的代码,最后一个参数表示了绘制 sprite 时的色调。如果我们把它改为 Color.White 那么将获得和原图一样的效果。你看,使用 XNA 轻易就能实现一些特效。
         再绘制几个 sprite
         现在我们有 4 个相同大小的 sprite 了。你已经掌握了 2D 绘图的基础,足够完成一个 2D 游戏的背景渲染。再次提醒,所有的 2D 绘图操作都因该在 Begin() End() 方法之间,而 SpriteBatch 方法调用又必须在 BeginScene() EndScene() 方法之间。简单的说,应该按照以下顺序:
--       开始渲染 3D 图形
l        渲染 3D 场景
l        开始渲染 2D 图形
n        渲染 2D 图片
l        结束 2D 渲染
--      结束 3D 渲染
         需要记住, 2D 图形的渲染和绘制他们的顺序有关系。在叠加区域,先渲染的图形总是会被后渲染的图形挡住,和在普通画布上绘图的原理一样。这也带领我们进入下一个话题,透明。
Transparent Blits
         首先,如果你要问我 Blits 是什么含意,那么我要告诉你,实际上你不必知道它是什么意思 =.= Blit 的含义来自于 BLT ,表示 Block Transfer ,意思是把一个平面的一部分复制到另一个平面。好了,关键的问题就在于我们如何把图片中,不透明的部分复制到已有图片上。
         为了渲染一个带透明效果的 sprite ,先来做一些辅助工作。首先,打开 windows 中的绘图板,任意绘制一个图形:
         哈哈,我绘制图形的能力确实很惊人,不是吗 ^_^ 。接下来,再创建一张同样大小的图片。上一张图片是我们希望显示的部分,而现在这张图片则作为它的透明遮罩:
         一般情况下,遮罩里白色部分是不透明的,而黑色部分则表示透明区域。把两张图片分别保存为 uglyStar.jpg uglyStarMask.jpg 。为了方便使用,把他们都添加到 Grahics 文件夹中。
         现在打开 DirectX SDK 中的 DxTex.exe 程序(它位于 sdk 安装路径的 Utilities/Bin/x86 件夹下)。选择 File->New Texture… ,在弹出的窗口中,把纹理尺寸设置为 32x32 ,把 Surface/Volume 格式设置为 Unsigned 32-bit: A8R8G8B8 ,如图所示:
         选择“ Open onto this surface”, 打开我们之前创建的红色星星 uglyStar.jpg
         选择“ Open onto Alpha Channel of this Surface” ,打开 uglyStarMask.jpg
         最后把文件保存为 star.dds ,并添加到 Graphics 文件夹。
         好了,现在有了一张带透明通道的图片,如何使用他呢。把它绘制到之前的天空上吧。添加如下代码:
………………….
private Microsoft.Xna.Framework.Graphics.Texture2D _spriteStar;
………………… .
public Sprites()
{
     ………………………
     _spriteStar = Texture2D.FromFile(graphics.GraphicsDevice, "../../Graphics/star.dds");
}
protected override void Draw()
{           
     …………… ..
     graphics.GraphicsDevice.BeginScene();          
    _sb.Begin(SpriteBlendMode.AlphaBlend);
     _sb.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.White);
     _sb.Draw(_sprite, new Vector2(_sprite.Width, 0.0f), Color.White);
     _sb.Draw(_sprite, new Vector2(_sprite.Width, _sprite.Height), Color.White);
     _sb.Draw(_sprite, new Vector2(0.0f, _sprite.Height), Color.White);
    _sb.Draw(_spriteStar, new Vector2(50.0f, 50.0f), Color.Yellow);
     _sb.End();
  ……………………………
}
         运行程序,你因该可以看到下图所示的结果 :

         注意到我们只显示了红色的部分没有?这都是透明遮罩的功劳。简要来说,你使用 DirectX 纹理工具,告诉了图片哪些部分需要渲染,哪些部分是透明的,注意这里使用了 dds 格式的文件,而不是 bmp 格式。
         你因该对这行代码比较感兴趣:
_sb.Begin(SpriteBlendMode.AlphaBlend);
         使用 AlphaBlend 作为 SpriteBlendMode 参数,会告诉 XNA 将要渲染一些带透明效果的图片。还记得我先前说过“ 大多数情况下,几乎所有的sprite都在同一个批次中”吗,好吧,我撒谎了-_-b。Alpha混合通常需要进行额外的计算,因此,应该把需要进行Alpha混合的sprite单独作为一个批次。一个批次用来绘制(静态)背景图片,另一个用来绘制带透明效果的前景物品。作为一条规则,你应该总是把需要alpha混合的sprite作为一个批次:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Components;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
namespace Chapter2
{
    partial class Sprites : Microsoft.Xna.Framework.Game
    {
        private Microsoft.Xna.Framework.Graphics.SpriteBatch _sbBackground;
        private Microsoft.Xna.Framework.Graphics.SpriteBatch _sbForeground;
        private Microsoft.Xna.Framework.Graphics.Texture2D _sprite;
        private Microsoft.Xna.Framework.Graphics.Texture2D _spriteStar;
        public Sprites()
        {
            this.AllowUserResizing = true;
            this.IsMouseVisible = true;
            InitializeComponent();
            _sbBackground = new SpriteBatch(this.graphics.GraphicsDevice);
            _sbForeground = new SpriteBatch(this.graphics.GraphicsDevice);
            _sprite = Texture2D.FromFile(this.graphics.GraphicsDevice, "../../Graphics/mcl_splashscreen_planet_2.tga");
            _spriteStar = Texture2D.FromFile(graphics.GraphicsDevice, "../../Graphics/star.dds");
        }
        protected override void Update()
        {
             float elapsed = (float)ElapsedTime.TotalSeconds;
            UpdateComponents();
        }
        protected override void Draw()
        {
             if (!graphics.EnsureDevice())
                return;
            graphics.GraphicsDevice.Clear(Color.Black);
            graphics.GraphicsDevice.BeginScene();
            _sbBackground.Begin();
            _sbBackground.Draw(_sprite, new Vector2(0.0f, 0.0f), Color.White);
            _sbBackground.Draw(_sprite, new Vector2(_sprite.Width, 0.0f), Color.White);
            _sbBackground.Draw(_sprite, new Vector2(_sprite.Width, _sprite.Height), Color.White);
            _sbBackground.Draw(_sprite, new Vector2(0.0f, _sprite.Height), Color.White);          
            _sbBackground.End();
            _sbForeground.Begin(SpriteBlendMode.AlphaBlend);
            _sbForeground.Draw(_spriteStar, new Vector2(50.0f, 50.0f), Color.White);
            _sbForeground.End();
            DrawComponents();
            graphics.GraphicsDevice.EndScene();
            graphics.GraphicsDevice.Present();
        }
    }
}
         好了,第二部分到次结束,下一章,我们将让 sprite 动起来~~。
 

这篇关于XNA教程(二)—— Into the 2D World的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/620745

相关文章

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

IDEA自动生成注释模板的配置教程

《IDEA自动生成注释模板的配置教程》本文介绍了如何在IntelliJIDEA中配置类和方法的注释模板,包括自动生成项目名称、包名、日期和时间等内容,以及如何定制参数和返回值的注释格式,需要的朋友可以... 目录项目场景配置方法类注释模板定义类开头的注释步骤类注释效果方法注释模板定义方法开头的注释步骤方法注

Python虚拟环境终极(含PyCharm的使用教程)

《Python虚拟环境终极(含PyCharm的使用教程)》:本文主要介绍Python虚拟环境终极(含PyCharm的使用教程),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录一、为什么需要虚拟环境?二、虚拟环境创建方式对比三、命令行创建虚拟环境(venv)3.1 基础命令3

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Python 安装和配置flask, flask_cors的图文教程

《Python安装和配置flask,flask_cors的图文教程》:本文主要介绍Python安装和配置flask,flask_cors的图文教程,本文通过图文并茂的形式给大家介绍的非常详细,... 目录一.python安装:二,配置环境变量,三:检查Python安装和环境变量,四:安装flask和flas

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.