关于在WP7的XNA开发模式中引入广告 Ad

                昨天小弟发现自己犯了个很严重的错误,那就是LGame的C#版启动类,在默认情况下没有调用父类Game的base.Update和base.Draw(base相当于Java版的super),导致XNA本身的渲染机制无法生效(LGame本身的渲染是正常的,缺了此两项,只是意味着引入XNA组件时,相关的XNA组件不会被渲染,操作也不会被执行罢了……),连累着插入XNA的广告组件也无法显示(话说改下源码,在相关函数重载部分调用上述两项就会正常了)~

为了弥补前失,所以小弟今天特意下载了一些支持XNA的广告SDK,并且改进了XNA与LGame的交互机制,做成了程序示例放入C#版中(只显示广告条和FPS的空项目,方便套用),下面是微软提供的Advertising广告,以及第三方XNA广告组件wp7adrotator和LGame的混用示例。

Advertising

using Loon;using Loon.Utils.Debug;using Loon.Core.Graphics;using Microsoft.Xna.Framework;using Microsoft.Advertising.Mobile.Xna;using System.Diagnostics;using System.Device.Location;using System;namespace LGameAd{    /// <summary>    /// 构建XNA监听,用以展示广告    /// </summary>    public class ADListener : XNAListener    {        //Advertising测试用标记(微软硬性规定,只有传这个才能启动Advertising测试)        private static readonly string ApplicationId = "test_client";        //广告单元ID(测试时只支持4种显示模式,就是Image480_80、Image480_80、Image300_50、TextAd,正式ID后才能自定义。)        private static readonly string AdUnitId = "Image480_80";        private DrawableAd bannerAd;        //广告驱动定位器(用来通过GPS/AGPS找到你手机的物理位置)        private GeoCoordinateWatcher gcw = null;        /// <summary>        /// LGame监听接口,用来监听标准XNA中Game类的构建        /// </summary>        /// <param name="game"></param>        public void Create(Game game)        {        }        /// <summary>        /// LGame监听接口,用来监听标准XNA中Initialize的启动        /// </summary>        public void Initialize(Game game)        {            //初始化AdGameComponent组件,并将其添加到游戏中            AdGameComponent.Initialize(game, ApplicationId);            game.Components.Add(AdGameComponent.Current);            //创建一个新的广告            CreateAd(game);        }        /// <summary>        /// LGame监听接口,用来监听标准XNA中LoadContent的启动        /// </summary>        public void LoadContent(Game game)        {        }        /// <summary>        /// LGame监听接口,用来监听标准XNA中UnloadContent的启动        /// </summary>        public void UnloadContent(Game game)        {        }        /// <summary>        /// LGame监听接口,用来监听标准XNA中Updatet的调用(每帧循环时都会调用)        /// </summary>        public void Update(Game game, GameTime gameTime)        {        }        /// <summary>        /// LGame监听接口,用来监听标准XNA中Draw的调用(每帧循环时都会调用)        /// </summary>        public void Draw(Game game, GameTime gameTime)        {        }        /// <summary>        /// 创建广告        /// </summary>        private void CreateAd(Game game)        {            // 创建指定大小的广告组件            int width = 480;            int height = 80;            // 定位到屏幕中央上方            int x = (game.GraphicsDevice.Viewport.Bounds.Width - width) / 2;            int y = 5;            bannerAd = AdGameComponent.Current.CreateAd(AdUnitId, new Rectangle(x, y, width, height), true);            // 添加广告事件监听            bannerAd.ErrorOccurred += new EventHandler<Microsoft.Advertising.AdErrorEventArgs>(bannerAd_ErrorOccurred);            bannerAd.AdRefreshed += new EventHandler(bannerAd_AdRefreshed);            // 并不是立即激活广告(在GPS定位成功后才激活)            AdGameComponent.Current.Enabled = false;            // 构建定位器            this.gcw = new GeoCoordinateWatcher();            // 监听定位器活动            this.gcw.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(gcw_PositionChanged);            this.gcw.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(gcw_StatusChanged);            this.gcw.Start();        }        private void bannerAd_AdRefreshed(object sender, EventArgs e)        {            Log.DebugWrite("Ad received successfully");        }        private void bannerAd_ErrorOccurred(object sender, Microsoft.Advertising.AdErrorEventArgs e)        {            Log.DebugWrite("Ad error: " + e.Error.Message);        }        private void gcw_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)        {            this.gcw.Stop();            bannerAd.LocationLatitude = e.Position.Location.Latitude;            bannerAd.LocationLongitude = e.Position.Location.Longitude;            AdGameComponent.Current.Enabled = true;            Log.DebugWrite("Device lat/long: " + e.Position.Location.Latitude + ", " + e.Position.Location.Longitude);        }        private void gcw_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)        {            if (e.Status == GeoPositionStatus.Disabled || e.Status == GeoPositionStatus.NoData)            {                AdGameComponent.Current.Enabled = true;                Log.DebugWrite("GeoCoordinateWatcher Status :" + e.Status);            }        }        /// <summary>        /// LGame监听接口,用来监听标准XNA中Dispose的调用(游戏结束时才会调用到)        /// </summary>        public void Dispose(Game game, bool disposing)        {            if (disposing)            {                if (this.gcw != null)                {                    this.gcw.Dispose();                    this.gcw = null;                }            }        }    }    public class Game1 : LFXPlus    {        public override void OnMain()        {            //加载LGame默认资源(不进行此操作,LGame内置的模拟按钮之类功能无法使用)            XNAConfig.Load("assets/loon.def");            //加载字体文件(此处是预编译好的xnb文件,也可以加载Content下的)            XNAFont = new LFont("assets", "black", 0, 20);            //注册AD监听(标准XNA事件监听)            SetXNAListener(new ADListener());            //设定启动参数            LSetting setting = new LSetting();            setting.fps = 60;            setting.width = 480;            setting.height = 320;            setting.showFPS = true;            setting.landscape = true;            //注册初始Screen            Register(setting, typeof(ScreenTest));        }        public override void OnGameResumed()        {        }        public override void OnGamePaused()        {        }    }}

然后,是利用wp7adrotator这个开源的第三方广告组件,加载AdDuplex广告(此物也支持Admob)。


using System;using System.Windows;using AdRotatorXNA;using Microsoft.Xna.Framework;using Microsoft.Xna.Framework.Graphics;using Microsoft.Xna.Framework.Input;using Loon;using Loon.Core.Graphics;namespace AdRotatorExampleXNA{    /// <summary>    /// 创建XNA监听器(稍微解释一下LGame中所谓的XNA监听器。本质上说,LGame-XNA版其实就是一个XNA的封装马甲。所以此监听器的实际作用,就是    /// 在LGame处理完毕后,把XNA应有的操作权限在监听中显示出来罢了~)    /// </summary>    public class ADListener : XNAListener     {        public void Create(Game gamne)        {        }        public void Initialize(Game game)        {            // 初始化广告组件            AdRotatorXNAComponent.Initialize(game);                        //硬编码的话就填下面这些            //AdRotatorXNAComponent.Current.PubCenterAppId = "test_client";            //AdRotatorXNAComponent.Current.PubCenterAdUnitId = "Image480_80";            //AdRotatorXNAComponent.Current.AdDuplexAppId = "0";            //AdRotatorXNAComponent.Current.InneractiveAppId = "DavideCleopadre_ClockAlarmNightLight_WP7";            //AdRotatorXNAComponent.Current.MobFoxAppId = "474b65a3575dcbc261090efb2b996301";            //AdRotatorXNAComponent.Current.MobFoxIsTest = true;            //读取配置文件的话就填下面这些(本例为读取AdDuplex的测试广告,AdRotator也支持Admob广告)            //定位广告位置            AdRotatorXNAComponent.Current.AdPosition = new Vector2(0,720);            //设定默认的广告图片            AdRotatorXNAComponent.Current.DefaultHouseAdImage = game.Content.Load<Texture2D>(@"Content/AdRotatorDefaultAdImage");            //当点击默认广告时,指向此操作。            AdRotatorXNAComponent.Current.DefaultHouseAdClick += new AdRotatorXNAComponent.DefaultHouseAdClickEventHandler(Current_DefaultHouseAdClick);            //用以选择广告幻灯效果的弹出方向            AdRotatorXNAComponent.Current.SlidingAdDirection = SlideDirection.None;            //选择本地的广告配置文件地址(针对不同的广告商,此处配置效果不同,以具体广告商提供的配置方式为准)            AdRotatorXNAComponent.Current.DefaultSettingsFileUri = "defaultAdSettings.xml";            //设定远程配置文件(可选项,非必填)            AdRotatorXNAComponent.Current.SettingsUrl = "http://xna-uk.net/adrotator/XNAdefaultAdSettingsV2.xml";            //添加广告组件到XNA画面当中            game.Components.Add(AdRotatorXNAComponent.Current);        }        void Current_DefaultHouseAdClick()        {            try            {                MessageBox.Show("非常感谢您点了小弟的广告^_^");            }            catch { }        }        public void LoadContent(Game game)        {        }        public void UnloadContent(Game game)        {        }        public void Update(Game game,GameTime gameTime)        {         }        public void Draw(Game game, GameTime gameTime)        {        }        public void Dispose(Game game, bool close)        {        }    }    public class Game1 : LFXPlus    {        public override void OnMain()        {            //加载LGame默认资源(不进行此操作,LGame内置的模拟按钮之类功能无法使用)            XNAConfig.Load("content/loon.def");            //加载字体文件(此处是预编译好的xnb文件 PS:当自定义资源文件夹命名为Content时,            //打包后会自动和标准的Content文件夹合并,这里做个演示。另,Windows系统不区分文件            //名大小写)            XNAFont = new LFont("content", "black", 0, 20);            //注册AD监听(标准XNA事件监听)            SetXNAListener(new ADListener());            //设定启动参数            LSetting setting = new LSetting();            setting.fps = 60;            setting.width = 480;            setting.height = 320;            setting.showFPS = true;            setting.landscape = false;            //注册初始Screen            Register(setting, typeof(ScreenTest));        }        public override void OnGameResumed()        {        }        public override void OnGamePaused()        {        }    }}


虽然目前很多Ad厂商只提供了Silverlight的广告SDK支持,但若考虑到国外第三方开发者的贡献,其实几乎所有常见WP7 Ad SDK(国外),都有办法通过XNA进行部署,并不一定非要Silverlight支持。

——但是,国内的广告商们似乎就没这么好运了。

今天(周二)试验了一下Silverlight+XNA混用,如预想中很好实现,目前已经添加了一个名为LSilverlight-0.3.3.dll的新编译文件与相关源码到WP7部分,等周五上传后就能支持Silverlight了(不立即传,是因为小弟目前版本多开(Java、C#、C/C++、HTML5(JS)),只能攒够修正一起来-_-|||),具体写法如下所示:

namespace LGameTest{    using System.Windows;    using System.Windows.Navigation;    using Loon;    using Loon.Core.Graphics;    using Loon.Core.Input;    using Loon.Core.Timer;    using Loon.Core.Graphics.OpenGL;    using Microsoft.Phone.Controls;    public class ScreenTest : Screen    {        public override LTransition OnTransition()        {            return LTransition.NewEmpty();        }        public override void OnLoad()        {        }        public override void Alter(LTimerContext c)        {        }        public override void Draw(GLEx g)        {                 }        public override void TouchDown(LTouch touch)        {        }        public override void TouchDrag(LTouch e)        {        }        public override void TouchMove(LTouch e)        {        }        public override void TouchUp(LTouch touch)        {        }    }    //微软硬性规定此处的PhoneApplicationPage必须是原始类,所以LGame在使用Silverlight时就只能采取如下加载方式了……    public partial class GamePage : PhoneApplicationPage    {        LSilverlightPlus plus;        public GamePage()        {            InitializeComponent();            //加载Silverlight数据到LGame            plus = LSilverlightPlus.Load(this, (Application.Current as App).Content, OnMain);        }        /// <summary>        /// 初始化事件        /// </summary>        /// <param name="plus"></param>        public void OnMain(LSilverlightPlus plus)        {            //加载LGame默认资源(不进行此操作,LGame内置的模拟按钮之类功能无法使用)            XNAConfig.Load("assets/loon.def");            //加载字体文件(此处是预编译好的xnb文件,也可以加载Content下的)            plus.XNAFont = new LFont("assets", "black", 0, 20);            //设定启动参数            LSetting setting = new LSetting();            setting.fps = 60;            setting.width = 480;            setting.height = 320;            setting.showFPS = true;            setting.landscape = false;            //注册初始Screen            plus.Register(setting, typeof(ScreenTest));        }        protected override void OnNavigatedTo(NavigationEventArgs e)        {            if (plus != null)            {                plus.OnNavigatedTo(e);                base.OnNavigatedTo(e);            }        }        protected override void OnNavigatedFrom(NavigationEventArgs e)        {            if (plus != null)            {                plus.OnNavigatedFrom(e);                base.OnNavigatedFrom(e);            }        }    }}



为了能兼顾国内的第三方广告商,所以小弟周五将添加Silverlight+XNA的混用类库(其实代码修改量很小,主要集中于渲染和输入输出接口部分,但小弟不做也不会凭空出现吧……望天……),到时会将上述修正一并上传到SVN。

——————————————

下面顺手发个微软与苹果平板发布时的对比视频,话说55秒开始神作了。

苹果iPad和微软Surface发布会对比视频


           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值