不到20萬的寶馬,車主們都說開起來很爽!

8百公里油耗(L):5。5/6。2/6。4車主百公里油耗(L):8。41/8。62驅動方式:前置前驅底盤懸挂:前麥弗遜/后多連桿式前排腿部空間(mm):890-1135前排高度(mm):940前排寬度(mm):1460後排腿部空間(mm):550-800後排高度(mm):900後排寬度(mm):1420實際體驗(體驗者178cm):前排頭部1拳/後排頭部4指/後排腿部1拳4指。

身為國內售價最接地氣的寶馬車型,寶馬1系三廂車型把定價下探到20萬元左右,它既能與奧迪A3展開競爭,也給寶馬的潛在用戶們提供了一個新選擇。

寶馬1系三廂車型採用了UKL前驅平台進行打造,並且搭載了B38系列1.5T發動機和分為高低功率調校的B48系列2.0T發動機,在傳動方面則採用來自愛信的6AT/8AT變速箱。

寶馬1系採用前驅的形式,雖然在駕駛感受上比以往的寶馬車型有所減弱,但它更易於控制,成本也得以下降。現在已經在使用這款車型的車主們對它有什麼評價?下面我們就來詳細看看。

長寬高:4456*1803*1448mm

軸距:2670mm

定位:緊湊型車

寶馬1系三廂的前臉采經典的“雙腎”造型中網,格柵造型的比較圓潤攻擊性不算十分突出。頭燈內帶有多邊形天使眼設計,並且大燈輪廓明顯向後延伸。稍有遺憾的是大燈沒有採用開眼角式設計,而側面輪廓緊湊而協調,短促的車尾造型提升了整車的運動感!

在內飾方面,它的布局分明清晰,中控台上部採用軟質材料覆蓋並且帶有縫線裝飾,中部配有高亮鋼琴烤漆面板,整體時尚感較好而且內飾的做工細緻、質感頗為優良!車門內襯也採用皮革和搪塑工藝材質包裹,整體質感良好。

發動機:1.5T/2.0T

最大馬力(pS):136/192/231

最大扭矩(Nm):220/280/350

變速箱:6AT/8AT

百公里加速(s):9.4/7.5/6.8

百公里油耗(L):5.5/6.2/6.4

車主百公里油耗(L):8.41/8.62

驅動方式:前置前驅

底盤懸挂:前麥弗遜/后多連桿式

前排腿部空間(mm):890-1135

前排高度(mm):940

前排寬度(mm):1460

後排腿部空間(mm):550-800

後排高度(mm):900

後排寬度(mm):1420

實際體驗(體驗者178cm):前排頭部1拳/後排頭部4指/後排腿部1拳4指。

感興趣的朋友可以點擊小程序查看詳細口碑,從口碑中可以看到,車主們對這款車型的操控感受,油耗控制能力和動力輸出比較滿意!而對於發動機NVH控制,一些配置的缺失有一些意見……

咱們發現寶馬1系的優惠還是比較大的,在廣州、武漢等地一般需要的搭配店內貸款、上保險、加裝飾等消費項目。

寶馬1系三廂車型在乘坐空間和內飾質感方面表現比較優良,是一款比較適合家用的車型,只是1.5T發動機採用直列3缸的設計結構,目前國內消費者對於這樣的發動機形式的接受度仍不算高。它的2.0T車型動力表現很強勁,只是售價門檻比較高。本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

動手造輪子:實現一個簡單的 AOP 框架

動手造輪子:實現一個簡單的 AOP 框架

Intro

最近實現了一個 AOP 框架 — FluentAspects,API 基本穩定了,寫篇文章分享一下這個 AOP 框架的設計。

整體設計

概覽

IProxyTypeFactory

用來生成代理類型,默認提供了基於 Emit 動態代理的實現,基於接口設計,可以擴展為其他實現方式

接口定義如下:

public interface IProxyTypeFactory
{
    Type CreateProxyType(Type serviceType);

    Type CreateProxyType(Type serviceType, Type implementType);
}

IProxyFactory

用來生成代理實例,默認實現是基於 IProxyTypeFactory 生成代理類型之後創建實例

接口定義如下:

public interface IProxyFactory
{
    object CreateProxy(Type serviceType, object[] arguments);

    object CreateProxy(Type serviceType, Type implementType, params object[] arguments);

    object CreateProxyWithTarget(Type serviceType, object implement, object[] arguments);
}

IInvocation

執行上下文,默認實現就是方法執行的上下文,包含了代理方法信息、被代理的方法信息、方法參數,返回值以及用來自定義擴展的一個 Properties 屬性

public interface IInvocation
{
    MethodInfo ProxyMethod { get; }

    object ProxyTarget { get; }

    MethodInfo Method { get; }

    object Target { get; }

    object[] Arguments { get; }

    Type[] GenericArguments { get; }

    object ReturnValue { get; set; }

    Dictionary<string, object> Properties { get; }
}

IInterceptor

攔截器,用來定義公用的處理邏輯,方法攔截處理方法

接口定義如下:

public interface IInterceptor
{
    Task Invoke(IInvocation invocation, Func<Task> next);
}

invocation 是方法執行的上下文,next 代表後續的邏輯處理,類似於 asp.net core 里的 next ,如果不想執行方面的方法不執行 next 邏輯即可

IInterceptorResolver

用來根據當前的執行上下文獲取到要執行的攔截器,默認是基於 FluentAPI 的實現,但是如果你特別想用基於 Attribute 的也是可以的,默認提供了一個 AttributeInterceotorResovler,你也可以自定義一個適合自己的 InterceptorResolver

public interface IInterceptorResolver
{
    IReadOnlyList<IInterceptor> ResolveInterceptors(IInvocation invocation);
}

IInvocationEnricher

上面 IInvocation 的定義中有一個用於擴展的 Properties,這個 enricher 主要就是基於 Properties 來豐富執行上下文信息的,比如說記錄 TraceId 等請求鏈路追蹤數據,構建方法執行鏈路等

public interface IEnricher<in TContext>
{
    void Enrich(TContext context);
}
public interface IInvocationEnricher : IEnricher<IInvocation>
{
}

AspectDelegate

AspectDelegate 是用來將構建要執行的代理方法的方法體的,首先執行註冊的 InvocationEnricher,豐富上下文信息,然後根據執行上下文獲取要執行的攔截器,構建一個執行委託,生成委託使用了之前分享過的 PipelineBuilder 構建中間件模式的攔截器,執行攔截器邏輯

// apply enrichers
foreach (var enricher in FluentAspects.AspectOptions.Enrichers)
{
    try
    {
        enricher.Enrich(invocation);
    }
    catch (Exception ex)
    {
        InvokeHelper.OnInvokeException?.Invoke(ex);
    }
}

// get delegate
var builder = PipelineBuilder.CreateAsync(completeFunc);
foreach (var interceptor in interceptors)
{
    builder.Use(interceptor.Invoke);
}
return builder.Build();

更多信息可以參考源碼: https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Aspect/AspectDelegate.cs

使用示例

推薦和依賴注入結合使用,主要分為以微軟的注入框架為例,有兩種使用方式,一種是手動註冊代理服務,一種是自動批量註冊代理服務,來看下面的實例就明白了

手動註冊代理服務

使用方式一,手動註冊代理服務:

為了方便使用,提供了一些 AddProxy 的擴展方法:

IServiceCollection services = new ServiceCollection();
services.AddFluentAspects(options =>
    {
        // 註冊攔截器配置
        options.NoInterceptProperty<IFly>(f => f.Name);

        options.InterceptAll()
            .With<LogInterceptor>()
            ;
        options.InterceptMethod<DbContext>(x => x.Name == nameof(DbContext.SaveChanges)
                                                || x.Name == nameof(DbContext.SaveChangesAsync))
            .With<DbContextSaveInterceptor>()
            ;
        options.InterceptMethod<IFly>(f => f.Fly())
            .With<LogInterceptor>();
        options.InterceptType<IFly>()
            .With<LogInterceptor>();

        // 註冊 InvocationEnricher
        options
            .WithProperty("TraceId", "121212")
            ;
    });
// 使用 Castle 生成代理
services.AddFluentAspects(options =>
    {
        // 註冊攔截器配置
        options.NoInterceptProperty<IFly>(f => f.Name);

        options.InterceptAll()
            .With<LogInterceptor>()
            ;
        options.InterceptMethod<DbContext>(x => x.Name == nameof(DbContext.SaveChanges)
                                                || x.Name == nameof(DbContext.SaveChangesAsync))
            .With<DbContextSaveInterceptor>()
            ;
        options.InterceptMethod<IFly>(f => f.Fly())
            .With<LogInterceptor>();
        options.InterceptType<IFly>()
            .With<LogInterceptor>();

        // 註冊 InvocationEnricher
        options
            .WithProperty("TraceId", "121212")
            ;
    }, builder => builder.UseCastle());

services.AddTransientProxy<IFly, MonkeyKing>();
services.AddSingletonProxy<IEventBus, EventBus>();
services.AddDbContext<TestDbContext>(options =>
{
    options.UseInMemoryDatabase("Test");
});
services.AddScopedProxy<TestDbContext>();

var serviceProvider = services.BuildServiceProvider();

批量自動註冊代理服務

使用方式二,批量自動註冊代理服務:

IServiceCollection services = new ServiceCollection();
services.AddTransient<IFly, MonkeyKing>();
services.AddSingleton<IEventBus, EventBus>();
services.AddDbContext<TestDbContext>(options =>
{
    options.UseInMemoryDatabase("Test");
});

var serviceProvider = services.BuildFluentAspectsProvider(options =>
            {
                options.InterceptAll()
                    .With<TestOutputInterceptor>(output);
            });

// 使用 Castle 來生成代理
var serviceProvider = services.BuildFluentAspectsProvider(options =>
            {
                options.InterceptAll()
                    .With<TestOutputInterceptor>(output);
            }, builder => builder.UseCastle());

// 忽略命名空間為 Microsoft/System 的服務類型
var serviceProvider = services.BuildFluentAspectsProvider(options =>
            {
                options.InterceptAll()
                    .With<TestOutputInterceptor>(output);
            }, builder => builder.UseCastle(), t=> t.Namespace != null && (t.Namespace.StartWith("Microsft") ||t.Namespace.StartWith("Microsft")));

More

上面的兩種方式個人比較推薦使用第一種方式,需要攔截什麼就註冊什麼代理服務,自動註冊可能會生成很多不必要的代理服務,個人還是比較喜歡按需註冊的方式,更為可控。

這個框架還不是很完善,有一些地方還是需要優化的,目前還是在我自己的類庫中,因為我的類庫里要支持 net45,所以有一些不好的設計改起來不太方便,打算遷移出來作為一個單獨的組件,直接基於 netstandard2.0/netstandard2.1, 甩掉 netfx 的包袱。

Reference

  • https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Aspect
  • https://www.cnblogs.com/weihanli/p/12700006.html

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

防疫封鎖 馬達加斯加狐猴族群獲得喘息

摘錄自2020年9月24日公視報導

安達西貝自然保護區是馬達加斯加島生態觀光的熱門地點之一,過去五個月因為新冠病毒疫情造成的封鎖以及邊境管制,當地最具代表性的動物狐猴,在原始雨林裡享受了沒有人類嘈雜群聚,寧靜自得的生活。島內九月起放寬了封鎖政策,觀光人數開始緩步回升,但因為國際航班仍然停擺,多數是馬達加斯加人自己的島內旅遊。

3月起陷入封鎖寒冬的旅遊業者,樂見顧客回歸,但富裕的外國觀光客進不來,仍然入不敷出。經濟壓力也傷害了自然環境。森林嚮導發現,最近林木被濫伐破壞的情況比過去30年都要嚴重。

馬達加斯加的旅遊業佔全國經濟的7%,堪稱重要支柱,而雨林生態體系脆弱,全國上百種的狐猴,幾乎都已經因為盜獵、暖化與森林砍伐,名列國際自然保護聯盟的紅色瀕危名單,其中30種更已經是極度瀕危,離滅絕只差一步。

生物多樣性
國際新聞
馬達加斯加
防疫
狐猴
動物與大環境變遷

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

福島農夫的七種土質實測:土壤輻射污染越高,作物污染越嚴重

文:宋瑞文(媽媽監督核電廠聯盟特約撰述)

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

花15萬買了輛看起來值50萬的國產車?

VV5的儲物格的數量不算特別多,擋把前方的儲物格並不能固定打開不知道是否是個例,除了常規的杯架等儲物空間以外,再也沒有其他的儲物格,隨身的物品需要合理安置。後備箱空間規整,兩側有網兜可以放一下容易滾動的物品。

很多人的心裏認為:自主品牌就是低廉,就是low的體現,買自主品牌車就是傻。其實,我們不應該人云亦云,雖然自主品牌的技術沉澱沒有外國傳統汽車大廠深厚,但我們也不應該一味地貶低,自主品牌需要我們的鼓勵和支持。

就像我們今天試駕的WEY VV5一樣,不熟悉WEY的朋友不用着急,簡單來說WEY是長城汽車旗下的子品牌,主打高端市場。WEY這個品牌在上市之初就受到質疑:自主品牌到底能不能打造豪華車?那麼到底中國的豪華車應該是怎樣的?帶你一一揭曉。

第一眼看到VV5的時候,有種熟悉又陌生的感覺,整體來看VV5跟大哥VV7相似度很高,如果不把兩輛車停在一起,很難分辨清楚到底是大哥還是小弟。VV5的車身尺寸都比VV7小一圈,也是更加符合VV5的定位。轎跑的造型動感十足,短小的尾部個人認為不太協調,沒有了轎跑車優雅流暢的尾部線條。LED大燈是VV5的標配,並且全車多處WEY車標演變過來的元素,例如豎條狀的LED日間行車燈,豎條狀的鑰匙等,無處不強調WEY的家族基因。20寸的大輪轂是頂配車型專屬,視覺效果滿分,尾部四齣的排氣也相當唬人。

走進車內,國人喜歡的豪華感統統奉上,例如真皮座椅,懸浮式中央显示屏,全景天窗等“高大上”的配置全部具備,中控台除了懸浮的中央显示屏以外,其餘的裝飾幾乎為零,層次感也不足,好在軟塑料的質感不錯。平底的方向盤給人一絲運動感,不過對於一台SUV來說,裝飾作用>實際效果,並且手很容易誤觸到多功能按鍵。中央多媒體系統依靠擋把后的旋鈕+按鈕控制,兩側則是行車輔助功能控制區域,例如車道保持,盲區監測,自動泊車等。全液晶儀錶很有科技感,能夠切換3種不同的主題,显示內容也不錯,日常使用的信息均有显示。

從外觀上看,VV5的漆面以及做工及格,同一塊鈑上下的厚度差別有點大,整體在97-115μm之間,縫隙還算不錯,除了尾門稍有點大以外,其餘的都在正常水平之內。

本次試駕的VV5使用了紅內飾,在運動感的營造上不錯,但可能不能滿足大部分人的需求。六向電動調節的座椅包裹性一般,坐起來適中,可能為了長途乘車不會太累而設計。

VV5的儲物格的數量不算特別多,擋把前方的儲物格並不能固定打開不知道是否是個例,除了常規的杯架等儲物空間以外,再也沒有其他的儲物格,隨身的物品需要合理安置。後備箱空間規整,兩側有網兜可以放一下容易滾動的物品。

VV5全系只有一種動力總成,2.0T+7速雙離合變速箱的組合,最大馬力197ps,最大扭矩355N*m,看起來參數不錯,發動機艙用塑料板封起來,看起來比較整潔,但不利於機艙的散熱。

雙離合變速箱也是偏向舒適調校,換擋動作不快,換來的是平順性。在中段加速的時候,變速箱不願降擋,而且降擋速度很慢,給下動力請求后需要等待一會才會降擋。總體來說變速箱表現一般。

VV5的百公里加速時間為9.5S,制動距離為37.8米,表現優秀。

開起來發動機的渦輪遲滯明顯,號稱2000rpm就能達到峰值扭矩,但開起並沒有什麼爆發感,整體動力輸出偏平順,日常使用還好,激烈一點駕駛就有點不盡人意了。

VV5的轉向手感有3種模式可調,總體來說普通模式會稍微適合日常駕駛,方向盤隔絕掉所有的路感,盡量做到舒適。

底盤的厚實感VV5的確做得不錯,懸挂的表現則不盡人意,前段硬後段軟,快速過彎支撐性一般,走過連續顛簸,車廂會有一定的晃動。

VV5的隔音在同級別來說是前列水平,整體的隔音降噪都不錯,發動機噪音是VV5主要的噪音源,其餘的風噪路噪都隔絕得很好。

VV5全系只有兩款車型,超豪型和旗艦型,售價分別為15.00萬和16.30萬,兩者之間配置差距不大,如果預算充足可以選擇旗艦型,無論是20寸輪轂還是全液晶儀錶盤都是比較彰顯科技感,而車道保持系統會讓你在巡航的時候更安全。

總的來講,VV5的表現可以用“第一眼美女”來形容,第一眼看過去,轎跑的造型,大輪轂,全景天窗,真皮內飾,全液晶儀錶盤通通配備,給足你認為豪華的東西,所有東西看上去都很好,但真正開起來,VV5的不足就開始出現,變速箱表現不盡人意,懸挂動作不夠乾脆等都是VV5的不足之處。如果你僅僅是在市區行駛,需要有一台拉風的座駕,VV5可以滿足你的要求,15萬你還能要求這麼嚴格嗎?

本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

法國逐步禁馬戲團野生動物表演 即起停止圈養新鯨豚

摘錄自2020年9月29日自由時報報導

法國環境部長蓬皮里(Barbara Pompili)表示,法國政府決議將逐步禁止國內的馬戲團再使用野生動物表演,善待動物組織也在推特回應歡迎此政策,希望能盡快執行。

綜合外媒報導,法國政府決定將逐步禁止國內的馬戲團使用包括熊、老虎、獅子、大象等野生動物來作為表演。此外,即日起法國的三座海洋館也不能繁殖或引進圈養新的海豚及虎鯨。

蓬皮里表示,目前政府正在考慮為這些被圈養的鯨豚建立庇護所,但是永久性演出和動物園中的野生動物並不受到禁令影響。法國政府也會向馬戲團與海洋館的從事相關人員提供高達800萬歐元(約新台幣2億7086萬6144元)的援助方案,讓工作人員受到最小的衝擊。

蓬皮里說,政府也預計未來五年內將禁止養殖貂,因為業者養殖目的僅是為了取下貂皮。

生物多樣性
國際新聞
法國
馬戲團
展演動物

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

垃圾問題有解了! 科學家創造超級酶 幾天內「吃掉」塑膠

摘錄自2020年9月30日自由時報報導

根據《CNN》報導,英國樸茨茅斯大學(University of Portsmouth)發布聲明指出,研究團隊將PET水解酶與另一種酶結合,創造出全新的人造酶,這種新產物可對聚對苯二甲酸乙二酯(PET)快速作用,使得原本需要百年才能分解的PET,在短短數日內就被分解為基礎組成,可重複製造成全新的塑膠製品。

樸茨茅斯大學酶創新中心主任麥吉漢(John McGeehan)表示,對於全球性回收塑膠及減少塑膠污染行動,新創造出來的超級酶是一大突破,目前雖仍無法商業量產,但在研究資金充裕的情況下,前景十分樂觀。

麥吉漢表示,考量到超級酶分解PET的超強能力,若能成功開發量產,意味著可回收現有的塑膠製品重複使用,節省大量能源的同時,還可以解決苦惱全球的垃圾及碳排放問題。

污染治理
國際新聞
亂倒垃圾
回收塑膠

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

CocosCreator實現微信排行榜

1. 概述

不管是在現實生活還是當今遊戲中,各式各樣的排名層出不窮。如果我們做好一款遊戲,卻沒有實現排行榜,一定是不完美的。排行榜不僅是玩家了解自己實力的途徑,也是遊戲運營刺激用戶留存的一種途徑。在微信小遊戲中普遍存以下兩種排名

  • 好友關係排名
  • 世界排名

其中好友的排名,需要通過微信子域實現。在子域上下文中,只能調用微信提供相關的api,且數據傳輸只能進不能出。即使在子域中調用雲函數也不行。這個對數據很嚴格,開發略為複雜。但好處也很明顯

  • 無需用戶確認授權就可實現排名
  • 排名信息均為自己好友,刺激效果更明顯

儘管這樣,我們還是先實現世界排行。世界排行需要用戶授權。早期只需要調用wx.authorize就可以實現,現在很不穩定(好像廢棄了)。所以不得不通過生成一個授權按鈕來實現

2. 微信雲開發

微信小遊戲為開發者提供了一部分免費的雲環境。可以實現文件存儲,數據存儲以及通過雲函數實現服務端接口。開通方式也很簡單,這裏不做說明。既然要實現排名,優先選用雲函數來實現對應的api。要實現雲函數,需要在project.config.json文件中通過屬性cloudfunctionRoot指定雲函數目錄。由於,是通過cocoscretor開發,每次構建發布都會清空輸出內容。為了解決人肉複製粘貼,我們需要通過定製小遊戲構建模板實現微信小遊戲所有代碼的管理。小遊戲地心俠士構建模板如下

從圖中,可以看到獲取openid、獲取世界排名、保存用戶授權信息等雲函數都放在cocoscreator代碼環境中。這樣在開發完成后,通過cocoscreator構建發布,對應的雲函數也會一起打包過去

3. 實現世界排行

3.1 獲取玩家openid

首先在構建模板的cloud-functions文件件中,使用npm初始一個名為getOpenId的node項目。初始好以後,運行npm install wx-server-sdk@latest --save。這樣就建立好了一個雲函數的基本框架。

我們在index.js文件,輸入以下代碼

// author:herbert 464884492
// project:地心俠士  獲取用戶openid
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

 

調用雲函數時,上下文中便可以得到玩家openid和uninid。玩家進入遊戲就先調用此函數,得到玩家的openid用於後邊更新玩家數據和獲取世界排行的條件。

小遊戲端調用雲函數前,需要初始雲環境。因為採用定製構建模板,所以我們直接在模板的game.js文件末尾初始我的雲環境

// author:herbert 464884492
// 地心俠士 初始雲環境
....
wxDownloader.init();
window.boot();

//初始化雲調用
this.wx.cloud.init({
    traceUser: true,
    env: 'dxxs-dxxs'
});
...

  

後續調用雲函數中,第一步都是要獲取openid,這裏定義一個全局變量將其保存起來,調用方法如下

// author:herbert 464884492
// 地心俠士 玩家openid
private static openId: string = null;
private static initenv() {
  return new Promise((resolve, reject) => {
      if (!this.wx) reject();
      //直接使用本地緩存
      if (this.openId != null) resolve();
      // 調用雲函數獲取
      this.wx.cloud.callFunction({
          name: 'getOpenId',
          complete: res => {
              this.openId = res.result.openid;
              resolve();
          }
      });
  });
}

 

3.2 動態生成授權按鈕

先看下地心俠士布局界面

上圖中可以看到,地心俠士虛擬了一個遊戲操作區域。玩家聚焦到世界排行時,需要渲染一個授權按鈕在確定的位置。需求很簡單,可考慮到移動端多分辨率,這個操作就變得複雜了。需要做屏幕適配。地心俠士採用自適應寬度的適配策略,配置如下圖

遊戲運行時獲取實際分辨率的寬度與設計的寬度相除,變可知道當前寬度變化比列,鍵盤容器九宮格使用了主鍵widget底部111px,高度161px。確定按鈕寬度105px

微信小遊戲以左上角為原點,通過topleft確定位置。然而,cocoscreator以左下角為原點,所以在計算top值時需要用屏幕寬度 – box上邊緣y坐標。適配代碼如下

// author:herbert 464884492
// 地心俠士 動態生成透明授權按鈕
 initUserInfoButton() {
  // 獲取設計尺寸
  let desingSize: cc.Size = cc.view.getDesignResolutionSize();
  //  獲取實際屏幕尺寸
  let screenSize: cc.Size = cc.view.getFrameSize();
  // 獲取寬度倍率
  let widthRate = screenSize.width / desingSize.width;
  // 獲取當前倍率下九宮格鍵盤實際高度
  let halfKcHeight = 161 * widthRate / 2;
  // 獲取當前倍率下確定按鈕實際寬度
  let btnwidth = this.btnKeySuer.width * widthRate;
  WxCloudFun.createUserinfoButton("", 
  // 確定按鈕中心點對應小遊戲left值 (屏幕寬度-確定按鈕實際寬度)/2
  // 定義實際授權按鈕size為105*40,所以還必須加上對應的偏差值
  // 以下代碼中left體現整體適配過程,不考慮中間過程可以直接使用
  // (屏幕寬度-授權按鈕)/2 即可得到left值
  screenSize.width / 2 - 52.5 * widthRate + (btnwidth - 105) / 2, 
  // Canvas 適配策略是 Fit Width,所以Canvas下邊沿不一定就是屏幕邊緣
  // 通過111*widthRate得到具體下沿值,在加上虛擬鍵盤一半高度,可得到中心位置
  // 由於微信原點在左上角,需要保持按鈕處於中心位置,坐標還需要上移一半按鈕高度
  screenSize.height - (111 * widthRate + halfKcHeight + 20),
 () => {
      this.keyCode = cc.macro.KEY.r;
      this.scheduleOnce(async () => {
          this.dlgRank.active = true;
          // 獲取排名數據
          await this.getRankInfo();
      }, 0);
  });
}

 

3.3 獲取用戶頭像昵稱信息

經過上一步驟的適配操作,只要玩家聚焦到【世界排行】,地心俠士虛擬鍵盤的確定按鈕正上方會覆蓋一個透明的userInfoButton,玩家點擊確定就會喚起授權對話框,然後在對應的回調函數就可以完成用戶數據保存操作

// author:herbert 464884492
// 地心俠士 獲取玩家基本信息
 public static createUserinfoButton(text: string, left: number, top: number, cb: Function) {
   this.userInfoButton = this.wx.createUserInfoButton({
      type: 'text',
      text: text,
      style: {
          left: left,
          top: top,
          height: 40,
          width: 105,
          lineHeight: 40,
          textAlign: 'center',
          fontSize: 16,
          backgroundColor: '#ff000000',// 透明
          color: '#ffffff',
      }
   });
   this.userInfoButton.hide();
   this.userInfoButton.onTap((res) => {
     // 將獲取到的用戶數據提交到雲端
      this.wx.cloud.callFunction({
          name: 'putUserinfo',
          data: { ...res.userInfo, openid: this.openId }
      });
      this.hideUserInfoButton();
      cb.call();
   });
   }

 

在代碼中,除了傳入玩家微信信息外。我還額外傳遞進入遊戲時就獲取的openid。正常情況下不需要的,因為,雲函數中天然會告訴你openid。不過,我們在後端使用了got獲取玩家頭像保存到雲端文件存儲中。引入此包后,後端就獲取不到openid了,相當奇怪。對應雲平台雲函數代碼如下

// author:herbert 464884492
// 地心俠士 雲函數保存玩家基本信息
const cloud = require('wx-server-sdk')
const got = require('got')
cloud.init()
// 雲函數入口函數
exports.main = async(event, context) => {
  const {
    nickName,
    avatarUrl,
    gender,
    openid
  } = event;
  let wxContext = cloud.getWXContext();
  // 如果後端拿不到openid就採用前端傳入的openid
  wxContext.OPENID = wxContext.OPENID || openid;
  const log = cloud.logger()
  log.info({
    tip: `正在請求頭像地址[${avatarUrl}]`
  })
  // 獲取頭像數據流
  const stream = await got.stream(avatarUrl);
  let chunks = [];
  let size = 0;
  const body = await (async() => {
    return new Promise((res, reg) => {
      stream.on('data', chunk => {
        chunks.push(chunk)
        size += chunk.length
        log.info({
          tip: `正在讀取圖片流信息:[${chunk.length}]`
        })
      })
      stream.on('end', async() => {
        const body = Buffer.concat(chunks, size)
        log.info({
          tip: `正在保存頭像文件:[${size}]`
        })
        res(body)
      })
    })
  })()
  //保存頭像到雲存儲
  const {
    fileID
  } = await cloud.uploadFile({
    cloudPath: `avatars/${wxContext.OPENID}.jpg`,
    fileContent: body
  })
  // 添加或更新玩家信息到數據庫
  const db = cloud.database()
  const {
    data
  } = await db.collection("dxxs").where({
    _openid: wxContext.OPENID
  }).get()
  const updateData = {
    fileId: fileID,
    nickName: nickName,
    sex: gender == 1 ? '男' : '女',
    avatarUrl: avatarUrl
  }
  if (data.length > 0) {
    log.info({
      tip: `正在修改數據庫信息:[${size}]`
    })
    await db.collection("dxxs").doc(data[0]._id).update({
      data: updateData
    })
  } else {
    log.info({
      tip: `正在添加數據庫信息:[${size}]`
    })
    await db.collection("dxxs").add({
      data: { ...updateData,
        _openid: openid
      }
    })
  }

  return {
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID
  }
}

 

3.4 獲取排行數據

保存完用戶數據后,通過一個回調函數,實現了玩家排名數據獲取。細心的朋友可以在前邊授權按鈕適配的章節看到await this.getRankInfo();這句代碼。後端雲函數就是一個簡單數據查詢。效果圖如下

從上圖可以看到,我實現了三個維度排名,需要在前端需要傳入排名字段。對應代碼如下

// author:herbert 464884492
// 地心俠士 獲取排名信息
 public static async getWorldRanking(field: string = "level") {
     const { result } = await this.wx.cloud.callFunction({
         name: 'getWordRanking',
         data: { order: field }
     });
     return result.ranks;
 }

 

雲函數代碼如下

// author:herbert 464884492
// 地心俠士 雲函數返回排名信息
const cloud = require('wx-server-sdk')
cloud.init()
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const db = cloud.database();
  const {
    order = "level"
  } = event;

  const openData = await db.collection("dxxs")
    .orderBy(order, "asc")
    .get()
  const ranks = openData.data.map(item => {
    return {
      openid: item._openid,
      [order]: item[order],
      nickName: item.nickName,
      fileId: item.fileId,
      avatarUrl: item.avatarUrl
    }
  });
  return {
    ranks: ranks,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID
  }
}

 

4. 總結

  • 微信子域數據很嚴格,數據只進不出。調用雲函數也不行
  • 雲函數中使用http請求,可能會得不到openid
  • 屏幕適配知道定位原則,也可以很簡單
  • avatarUrl通過Sprite現實頭像,需要設置安全域名
  • 目前部分華為手機分享截屏出現黑屏使用canvas.toTempFilePath就可以解決

這裡有一個CoscosCreator遊戲開發群,歡迎喜歡聊技術的朋友加入

 

 

歡迎感興趣的朋友關注我的訂閱號“小院不小”,或點擊下方二維碼關注。我將多年開發中遇到的難點,以及一些有意思的功能,體會都會一一發布到我的訂閱號中

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

研究示警 亞馬遜雨林四成似莽原 逼近不可逆臨界點

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?

3.6L的美系V6,4.0L的普拉多,這麼牛的車也就10來萬?

0L售價不到9萬元,而且作為一台豐田的硬派越野車,其可靠性之高是毋庸置疑的。只是作為一款十多年的老車,它將會面臨嚴峻的年檢考驗,甚至被納入黃標範圍無法上路。不過如果你已經有一台代步車,那麼買一台這樣的經典硬派越野車,只用作純粹的越野撒歡之用,其實也是挺不錯的。

10萬元以內,買什麼車好?很多年輕消費者都會在10萬元上下的價格區間選擇自己的第一台車,而很多時候他們都會把選擇範圍局限本田飛度、大眾polo、寶駿510這樣的熱門車型,但是如果我們將目光投向二手市場,也許我們會有驚喜發現哦!

MINI One 1.6L

MINI可以說是目前國內形象最個性最時尚的品牌之一,在目前的二手市場上,行駛里程在10萬公里左右的2011款MINI One售價約在9到10萬元,小巧個性的造型和動力表現還不錯的1.6L自然吸氣發動機很適合在城市作日常通勤用車。不過需要注意的是,雖然油液、濾芯等消耗品的常規保養項目成本不高,但MINI的零部件價格較高,一旦需要更換零件,還是需要花不少錢的。

薩博 9-5

一個當年以其飛機生產商出身而自豪的瑞典品牌,薩博9-5毫無疑問是一款極其獨特的中大型轎車。由於車型極其冷門,目前二手市場上哪怕是搭載高功率版本2.3T發動機的薩博9-5 Aero,售價也不過10萬元;不過車源稀少且市面上配件難找,後期維護保養比較麻煩。

克萊斯勒300C

如果說國內還有哪些車擁有典型的美式風格,那麼克萊斯勒300C毫無疑問是其中之一;平直的線條,巨大的鍍鉻中網,大尺寸輪圈和3.6L自然吸氣V6發動機,克萊斯勒如此“肌肉化”的外觀設計肯定會引來不少路人的目光。目前二手市場上的舊款克萊斯勒300C大多是較早的2004款車型,行駛里程都在10萬公里以上,售價在8到9萬元左右。對於這款典型的美式轎車,選擇它就意味着需要做好面對驚人油耗的準備。

豐田普拉多

除了每天的城市穿梭,當然也會有一部分人想要在閑暇時開着車到野外撒歡,那麼一台強大的越野車就是必不可少的穿越工具。豐田蘭德酷路澤系列的普拉多車型就是個不錯的選擇。目前二手市場上一台2001款的豐田普拉多4.0L售價不到9萬元,而且作為一台豐田的硬派越野車,其可靠性之高是毋庸置疑的;只是作為一款十多年的老車,它將會面臨嚴峻的年檢考驗,甚至被納入黃標範圍無法上路;不過如果你已經有一台代步車,那麼買一台這樣的經典硬派越野車,只用作純粹的越野撒歡之用,其實也是挺不錯的。

日產奇駿

當然,如果你需要一台平時也能用來代步的越野車,那麼2010款的日產奇駿就能幫到你了。目前市面上行駛里程在10萬公里左右的2010款日產奇駿,售價普遍在9萬元上下。

斯巴魯森林人

而除了日產奇駿之外,10萬元預算甚至能在二手市場找到一台2008款的斯巴魯森林人2.0XS!水平對置發動機搭配強大的全時四驅系統,斯巴魯森林人就是一款通過性出色,而且形象更加高檔的優秀SUV車型。

豐田凱美瑞

那麼如果你性格成熟穩重,而且想要更多的估計家庭需要,甚至想要有一些商務范,豐田凱美瑞就是個很不錯的選擇。10萬元預算,能夠在二手市場上找到車況不錯的舊款凱美瑞,2011款到2013款都有非常豐富的車源,能夠慢慢從中挑選車況優秀、價格合理的車源。

本田奧德賽

MpV是非常出色的家用車型,目前,只需10萬,就能買到一台行駛里程在10萬公里以內的舊款奧德賽。本田奧德賽是一款非常成功的家用MpV車型,由於舊款造型比較接近旅行車,奧德賽的外觀看上去不會顯得太過商務化,自己平日里開着上班也不會有濃重的“司機范”。

斯巴魯翼豹

說到激情,說到玩樂,有興趣的朋友可以在市場上尋找一下斯巴魯翼豹的身影,目前市面上價格在10萬元以內的斯巴魯翼豹大多是搭載EJ20自然吸氣發動機和手自一體變速箱的版本,因此購買后還需多花點心思在後期改裝部分,才會體現出斯巴魯翼豹的“好玩”之處。

寶馬1系

156馬力的2.0L發動機,前置后驅布局,再搭配出色的6擋手動變速箱,舊款寶馬1系的駕駛樂趣是相當高的。目前二手車市場價格只需要8到9萬元,性價比可謂相當高。

買車不一定都要買新車,尤其是對於年輕一代消費者來說,二手車甚至能以低廉的價格找到更加有趣的車型,上面提及的這些車不過是二手市場中好車群里的冰山一角。不過畢竟二手車的車況參差不齊,有意選擇二手車的朋友也要注意先了解清楚試車、驗車的竅門哦!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※教你寫出一流的銷售文案?