《Head First C#》外星人入侵WPF編寫源碼

来源:https://www.cnblogs.com/botinghub/archive/2019/11/05/11801484.html
-Advertisement-
Play Games

@ "TOC" 引言 自學的C ,看了幾本教材講的都是程式代碼,網上找的也有視屏,但都比較老了。只會打些代碼為不曉得為什麼要這樣打感覺很彆扭,在朋友的推薦下先選擇了這本《Head First C 》先大致的瞭解下C 。 這本書的第一章我就遇見了問題,要裝IDE選的是VS2012 for win8的, ...


目錄

@(外星人入侵(WPF編寫))

引言

自學的C#,看了幾本教材講的都是程式代碼,網上找的也有視屏,但都比較老了。只會打些代碼為不曉得為什麼要這樣打感覺很彆扭,在朋友的推薦下先選擇了這本《Head First C#》先大致的瞭解下C#。
這本書的第一章我就遇見了問題,要裝IDE選的是VS2012 for win8的,這完全和我的系統不配我是用的VS2017+win10,想著應該是一樣的,但是沒有找到windows store,我尋思著估計我只安裝了for .NET沒有安裝windows平臺通用的那個環境,要是選擇在安裝那個環境的話12G空間,懶得裝。書上說明瞭使用WPF可以打大部分代碼,那就將就著用吧!書上給了參考PDF的下載網址可是用梯子也連不上,打了首碼發現進了他們公司的主站。估計網址換了把,CSDN上也沒找到那個PDF資源。自己瞎琢磨著來吧,這個博客是個記錄,希望對你有用。

前期工作

  1. 打開VS,創建WPF窗體;
    創建界面
  2. 照書上一步一步來搭建界面,基本一樣
    在這裡插入圖片描述
  3. 搭建好了我們就來寫代碼,代碼裡面有點不一樣我會說明的

    代碼編寫

註意事項:

  1. 引用的地方:這裡你會發現沒有using windows.UI.Xaml;之類的引用。這是你沒安裝他的環境因而沒有這些動態庫。
    解決方法:用using System.Windows.*,就行,你會發現其實去掉UI,Xaml其他欄位都一樣。
  2. 關於事件裡面沒有PointerPressed和PointerMoved等等這個它可以發佈到平臺上平板也要用估計是他們把事件給優化了,不過不用慌,看得懂英文的就可以類推不就是個滑鼠按壓事件和滑鼠移動事件嗎?照著我們有的事件來就行。
    解決方法:使用MouseDown和MouseMoved代替其他事件一樣。
  3. PlayArea_MouseMove函數裡面有個Point的語句,是不是按照書上敲又報錯了!這個我也不曉得為啥給可能還是環境的問題吧!.NET的WPF確實沒有那幾個函數。不過仔細讀下就可以理解是獲取PlayArea裡面的滑鼠位置,進行滑鼠位置判斷的。網上查了下WPF獲取滑鼠位置的幾種方法這發現使用這種更合適跟簡單,還不用像書上那樣進行滑鼠的轉換,用e.GetPosition(playArea);直接就使用的是相對與playArea的滑鼠位置。
    解決辦法:使用e.GetPosition()

其他的倒沒有什麼問題,有問題留言,如果我可以幫助你的話。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace SaveHuman
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        Random random = new Random();
        DispatcherTimer enemyTimer = new DispatcherTimer();
        DispatcherTimer targetTimer = new DispatcherTimer();
        bool humanCaptured = false;
        public MainWindow()
        {
            InitializeComponent();

            enemyTimer.Tick += EnemyTimer_Tick;//2019.10.30 22點21分
            enemyTimer.Interval = TimeSpan.FromSeconds(2);//2秒增加一個敵人

            targetTimer.Tick += TargetTimer_Tick;
            targetTimer.Interval = TimeSpan.FromSeconds(.1);//0.1秒執行一次
        }
        /// <summary>
        /// 進度條計時器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TargetTimer_Tick(object sender, EventArgs e)
        {
            progressBar.Value += 1;
            if (progressBar.Value >= progressBar.Maximum)
            {
                EndTheGame();
            }
        }

        /// <summary>
        /// 游戲結束
        /// </summary>
        #region 游戲結束
        private void EndTheGame()
        {
            if (!playArea.Children.Contains(gameoverText))
            {
                enemyTimer.Stop();
                targetTimer.Stop();
                humanCaptured = false;
                starbutton.Visibility = Visibility.Visible;
                playArea.Children.Add(gameoverText);
            }
        }
        #endregion
        /// <summary>
        /// 添加敵人的計時器
        /// </summary>

        private void EnemyTimer_Tick(object sender, EventArgs e)
        {
            AddEnemy();
        }
        /// <summary>
        /// 點擊Star開始游戲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Starbutton_Click(object sender, RoutedEventArgs e)
        {
            StarGame();

        }
        /// <summary>
        /// 開始游戲初始化
        /// </summary>
        private void StarGame()
        {
            human.IsHitTestVisible = true;
            humanCaptured = false;
            progressBar.Value = 0;
            starbutton.Visibility = Visibility.Collapsed;
            playArea.Children.Clear();
            playArea.Children.Add(target);
            playArea.Children.Add(human);
            enemyTimer.Start();
            targetTimer.Start();
        }
        /// <summary>
        /// 添加敵人
        /// </summary>
        private void AddEnemy()
        {
            ContentControl enemy = new ContentControl();
            enemy.Template = Resources["EnemyTemplate"] as ControlTemplate;
            AnimateEnemy(enemy, 0, playArea.ActualWidth - 100, "(Canvas.Left)");
            AnimateEnemy(enemy, random.Next((int)playArea.ActualHeight - 100), random.Next((int)playArea.ActualHeight - 100), "(Canvas.Top)");
            playArea.Children.Add(enemy);

            enemy.MouseEnter += Enemy_MouseEnter;
        }
        /// <summary>
        /// 滑鼠進入敵人
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Enemy_MouseEnter(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
            {
                EndTheGame();
            }
        }
        /// <summary>
        /// 動畫函數
        /// </summary>
        /// <param name="enemy"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="propertyToAnimate"></param>
        private void AnimateEnemy(ContentControl enemy, double from, double to, string propertyToAnimate)
        {
            Storyboard storyboard = new Storyboard() { AutoReverse = true, RepeatBehavior = RepeatBehavior.Forever };
            DoubleAnimation animation = new DoubleAnimation()
            {
                From = from,
                To = to,
                Duration = new Duration(TimeSpan.FromSeconds(random.Next(4, 6)))
            };
            Storyboard.SetTarget(animation, enemy);
            Storyboard.SetTargetProperty(animation, new PropertyPath(propertyToAnimate));
            storyboard.Children.Add(animation);
            storyboard.Begin();
        }

        
        /// <summary>
        /// 人類是否到達目的地的判斷
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Target_MouseEnter(object sender, MouseEventArgs e)
        {
            if(targetTimer.IsEnabled && humanCaptured)
            {
                progressBar.Value = 0;
                Canvas.SetLeft(target, random.Next(100, (int)playArea.ActualWidth - 100));
                Canvas.SetTop(target, random.Next(100, (int)playArea.ActualHeight - 100));
                Canvas.SetLeft(human, random.Next(100, (int)playArea.ActualWidth - 100));
                Canvas.SetTop(human, random.Next(100, (int)playArea.ActualHeight - 100));
                humanCaptured = false;
                human.IsHitTestVisible = true;

            }
        }
        /// <summary>
        /// 滑鼠在游戲區域移動
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PlayArea_MouseMove(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
            {
                //獲取滑鼠相對於palyArea的位置,無需書上的轉換這是wpf與windows Store的不同
                //對於這個不理解可以把playArea改為null試試看看區別就曉得了
                Point pointerProsition = e.GetPosition(playArea);

                
                if((Math.Abs(pointerProsition.X-Canvas.GetLeft(human))>human.ActualWidth*3) || (Math.Abs(pointerProsition.Y - Canvas.GetTop(human)) > human.ActualHeight * 3))
                {
                    humanCaptured = false;
                    human.IsHitTestVisible = true;

                }
                else
                {
                    Canvas.SetLeft(human, pointerProsition.X - human.ActualWidth / 2);
                    Canvas.SetTop(human, pointerProsition.Y - human.ActualHeight / 2);

                }
            }
        }
        /// <summary>
        /// 滑鼠拖著人類離開游戲區域
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PlayArea_MouseLeave(object sender, MouseEventArgs e)
        {
            if (humanCaptured)
            {
                EndTheGame();
            }
        }

        /// <summary>
        /// 滑鼠左鍵點擊人類的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Human_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (enemyTimer.IsEnabled)
            {
                humanCaptured = true;
                human.IsHitTestVisible = false;
                //Console.WriteLine("滑鼠按下選中狀態:" + humanCaptured);

            }
        }

        
    }
}

只要努力沒有什麼困難可以難倒你,加油騷年!

————————————————————————————————Boting_ISME
在這裡插入圖片描述


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 樂觀鎖 樂觀鎖顧名思義就是在操作時很樂觀,認為操作不會產生併發問題(不會有其他線程對數據進行修改),因此不會上鎖。但是在更新時會判斷其他線程在這之前有沒有對數據進行修改,一般會使用版本號機制或CAS(compare and swap)演算法實現。簡單理解:這裡的數據,別想太多,你儘管用,出問題了 ...
  • start方法和run方法比較 很多人包括我自己也以前也認為run和start方法都可以啟動一個線程,並且兩者的功能都差不多,然後在學習的過程中認識到這是錯誤的,他們之間是 截然不同 的。先來看一段演示代碼: 輸出結果: 可以看到, 執行run方法的線程是主線程,而執行start方法的才是一個新的子 ...
  • 獲取 在刷機之前,需要在電腦上下載 Android Preview 包,一般我都是到 安卓中國 ,這裡可以下載最新的包。 手機 相對下載包的獲取,比較難的是有一部支持最新的安卓系統的手機,一般 Preview 版的系統都是預設支持 Google 自己的手機的。 主要有面向的是 Pixel 系列的手機 ...
  • 一、為什麼 物理地址=段地址x16+偏移地址? PS:剛開始學時,我都笨到不明白為什麼是2的N次方,咱把物理地址就當數字,電腦中數字是由很多位0或1自由組合的, 而每一位上要麼是0要麼是1,只有這兩種情況,所以N位就可以組成2的N次方個編號地址了 8086CPU的地址匯流排是20條(位),因此就可以 ...
  • 前言 在上一篇文章 "你公司到底需不需要引入實時計算引擎?" 中我講解了日常中常見的實時需求,然後分析了這些需求的實現方式,接著對比了實時計算和離線計算。隨著這些年大數據的飛速發展,也出現了不少計算的框架(Hadoop、Storm、Spark、Flink)。在網上有人將大數據計算引擎的發展分為四個階 ...
  • 1 public class Solution 2 { 3 public bool Find(int target, int[][] array) 4 { 5 if (array != null) 6 { 7 int rowCnt = array.Length - 1; 8 int colCnt = ...
  • C# 調用印表機列印文件,通常情況下,例如Word、Excel、PDF等可以使用一些對應的組件進行列印,另一個通用的方式是直接啟用一個列印的進程進行列印。示例代碼如下: ...
  • C# 獲取所有安裝了的印表機代碼如下: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...