使用canvas通過js製作一個小型英雄抓怪獸的2D小游戲

来源:https://www.cnblogs.com/laoqitong/archive/2019/04/16/10716880.html
-Advertisement-
Play Games

<img src="https://image.baidu.com/search/detail?ct=503316480&z=undefined&tn=baiduimagedetail&ipn=d&word=tu&step_word=&ie=utf-8&in=&cl=2&lm=-1&st=undef... ...


首先,這是一個HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Simple Canvas Game</title>
</head>
<body>
</body>
</html>
<script src="../js/canvas.js"></script>

然後,是canvas.js的內容,主要操作都在js中:

var cvs = document.createElement('canvas'); // 創建canvas標簽
var ctx = cvs.getContext('2d');

cvs.width = 512;    // 設置canvas的寬度
cvs.height = 480;   // 設置canvas的高度
// cvs.style = 'border:1px solid #000;';   // 設置canvas樣式
document.body.appendChild(cvs); // 將新建的canvas渲染到頁面
// console.log(ctx);

// 準備背景圖片
var bgReady = false;
var bgImg = new Image();
bgImg.onload = function () {
    bgReady = true;
}
bgImg.src = "../src/images/games/images/background.png";

這是背景圖片

// 準備英雄圖片
var heroReady = false;
var heroImg = new Image();
heroImg.onload = function () {
    heroReady = true;
}
heroImg.src = "../src/images/games/images/hero.png";

這是英雄圖片

// 準備怪獸圖片
var monsterReady = false;
var monsterImg = new Image();
monsterImg.onload = function () {
    monsterReady = true;
}
monsterImg.src = "../src/images/games/images/monster.png";

這是怪獸圖片

// 定義游戲對象
var hero = {
    speed: 256  // 控制英雄每秒移動多少像素
}
var monster = {};
var monsterCaught = 0;  // 抓到的怪獸數量

// 處理用戶的鍵盤控制
var keysDown = {};
// 監聽鍵盤按下事件
addEventListener('keydown', function (e) {
    keysDown[e.keyCode] = true;
}, false);
// 監聽鍵盤抬起事件
addEventListener('keyup', function (e) {
    delete keysDown[e.keyCode];
}, false);

// 重開新一輪游戲的事件處理
var reset = function () {
    hero.x = cvs.width / 2;
    hero.y = cvs.height / 2; // 英雄的初始坐標

    monster.x = 32 + (Math.random() * (cvs.width - 64));
    monster.y = 32 + (Math.random() * (cvs.height - 64));
};

// 更新游戲對象事件處理
var update = function (modifier) {
    if (87 in keysDown) {   // 鍵盤按下“W”
        hero.y -= hero.speed * modifier;
    }
    if (83 in keysDown) {   //  鍵盤按下“S”
        hero.y += hero.speed * modifier;
    }
    if (65 in keysDown) {   // 鍵盤按下“A”
        hero.x -= hero.speed * modifier;
    }
    if (68 in keysDown) {   // 鍵盤按下“D”
        hero.x += hero.speed * modifier;
    }

    // 碰到上下左右邊界時
    if (hero.x < 0) { // 左邊界
        hero.x = cvs.width - 32;
    } else if (hero.x > cvs.width) {    // 右邊界
        hero.x = 0;
    } else if (hero.y < 0) {    // 上邊界
        hero.y = cvs.height - 32;
    } else if (hero.y > cvs.height) {    // 下邊界 
        hero.y = 0
    }

    // 判斷是否抓住怪獸
    if (
        hero.x <= (monster.x + 32) &&
        monster.x <= (hero.x + 32) &&
        hero.y <= (monster.y + 32) &&
        monster.y <= (hero.y + 32)
    ) {
        ++monsterCaught;
        reset();
    }
}

// 渲染物體
var render = function () {
    if (bgReady) {
        ctx.drawImage(bgImg, 0, 0);
    }
    if (heroReady) {
        ctx.drawImage(heroImg, hero.x, hero.y);
    }
    if (monsterReady) {
        ctx.drawImage(monsterImg, monster.x, monster.y);
    }

    // 上色
    ctx.fillStyle = "rgb(250,250,250)";
    ctx.font = "24px Helvetica";
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    ctx.fillText('抓到的怪獸數量:' + monsterCaught, 32, 32);
}

// 主迴圈函數
var main = function () {
    var now = Date.now();

    var delta = now - then;
    update(delta / 1000);
    render();
    then = now;

    var w = window;
    requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;
    requestAnimationFrame(main);
};

// 啟動游戲
var then = Date.now();
reset();
main();

這是整個游戲運行的效果圖

初來博客園,還有許許多多不瞭解的地方,還請多多諒解。
成果展示:https://lqitong.github.io/canvas/
資源都在我的 github 上邊兒,有興趣的博友可以上去看看:https://github.com/LQiTong/canvas


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

-Advertisement-
Play Games
更多相關文章
  • 對ctrl+a後拖動的問題做了處理 ...
  • ‘手寫 ’ 這個詞 ,面試是不是聽過無數遍呢 ! 今天我們來手寫一個這樣的事件委托函數 =》 function( parent, selector, type , handle) {} 你需要傳遞的參數分別是: parent: 事件綁定的父級 selector: 選擇器, type: 事件類型 ha ...
  • JS繼承的實現方式: 既然要實現繼承,那麼首先我們得有一個父類,代碼如下: 1、原型鏈繼承 核心: 將父類的實例作為子類的原型 特點: 1.非常純粹的繼承關係,實例是子類的實例,也是父類的實例 2.父類新增原型方法/原型屬性,子類都能訪問到 3.簡單,易於實現 缺點: 1.可以在Cat構造函數中,為 ...
  • <!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>飄舞的小球</title> <style type="text/css"> div { width: 100px; height: 100px; line-height: 100px ...
  • 第一步:引入clipboard插件JS 第二步:在HTML代碼加入clipboard相關屬性 其中data-clipboard-target、data-clipboard-text、data-clipboard-action是clipboard插件自帶的屬性,id和class可以自己任選一個用來調用 ...
  • 1 內部插入 1.1 append(content | fn) 向每個匹配的元素內部追加內容。 參數: (1) content:要追加到目標中的內容。 (2) function(index, html):返回一個HTML字元串,用於追加到每一個元素裡面。index為元素索引,html為元素內的htm ...
  • 前端er經常都會遇到使用 的時候,特別是弄後臺管理的報表等地方,而 是`echarts`的vue版本(餓了麽寫的),基本上能應付普通的圖表。 "傳送門" 隱藏提示框與圖例 v charts渲染的標題過於簡單,有時候跟設計稿的很不一樣,需要自己用樣式重新寫,這時候,你可以選擇隱藏預設的提示框和標題 設 ...
  • 小程式中經常會遇到要生成圖片的需求,圖片一般會加上用戶的頭像和昵稱之類的,頭像只需要把騰訊功能變數名稱添加到request和download列表中,使用wx.getImageInfo()就可以緩存到本地,成功的回調再添加進canvas中生成圖片。 如果要文字在某個位置居中,canvas中文字怎麼根據文字長短 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...