HTML5游戏实战(2):90行代码实现捕鱼达人

2023-11-19

捕鱼达人是一款非常流行的游戏,几年里赚取了数以千万的收入,这里借用它来介绍一下用Gamebuilder+CanTK开发游戏的方法。其实赚钱的游戏未必技术就很难,今天我们就仅用90来行代码来实现这个游戏。 

CanTK(Canvas ToolKit)是一个开源的游戏引擎和APP框架,是开发HTML5游戏和APP的利器,如果你喜欢它,请在github上给它加星,您的支持是我们努力的动力:https://github.com/drawapp8/cantk

0.先Show一下最终成果:

在线运行:http://www.tangide.com/apprun.html?appid=previewupyunosgames1-841431856568571

在线编辑:http://www.tangide.com/gamebuilder.php?appid=previewupyunosgames1-841431856568571

1,新建一个项目,删除场景里的球和地面,把手机设置成横屏,然后设置场景的物理引擎参数,把X/Y方向的重力设置为0。

设置场景的背景图片:

效果如下:

2,在场景中放一个图片,如下图设置它的属性。

3,在图片中再放一个帧动画,用来表示大炮,如下图设置它的属性。

4,在场景中再放一个帧动画,用来表示鱼,如下图设置它的属性。

通过拷贝&粘贴,创建10条鱼,名称分别命名为ui-fish1到ui-fish10。得到下面的效果:

5,在场景中再放一个帧动画,用来表示金币,如下图设置它的属性。

6,在场景中再放一个帧动画,用来表示炮弹,如下图设置它的属性。

7,在底部的图片中放一个图片字体,用来表示总金币数量,如下图设置它的属性。

8,在场景中中放一个图片字体,用来表示单次金币数,如下图设置它的属性。

9,在底部的图片中放两个按钮,用来改变大炮的威力,如下图设置它的属性。

到此界面基本完成了(后面可能需要做些调整),效果如下:

10,现在我们开始写代码。

在场景的onOpen里定义几个函数:

var win = this;
function isObjInvisible(obj) {return !obj.visible;}
//当炮弹和鱼移动到场景之外时,把它们设置为不可见不可用,后面重用这些对象,以减小内存开销。
function handleOnMoved() {
    var x = this.x, y = this.y, r = x + this.w, b = y + this.h, w = win.w, h = win.h;
    if(x > w || y > h || r < 0 || b < 0) {
        this.setVisible(false).setEnable(false);
    }
}
//定时产生鱼
function makeFish() {
    if(!win.info) return;
    var info = win.info,cannon = info.cannon;
    var fish = info.fishs.find(isObjInvisible);
    if(!fish && info.fishs.length < 20) {
        var index = Math.floor(10 * Math.random())+1;
        fish = win.dupChild("ui-fish"+index);
        
    }
    if(fish) {
        info.fishs.push(fish);
        var y = Math.max(0, Math.floor((win.h - info.bottom.h) * Math.random() - fish.h));
        var x =  y%2 ? -fish.w : win.w;
        var vx = x > 0 ? -1 : 1;
        var rotation = x > 0 ? Math.PI : 0;
        fish.setPosition(x, y).setVisible(true).setEnable(true).setV(vx, 0).setRotation(rotation).play("live");
    }
    setTimeout(makeFish, 500);
}
//初始化游戏
win.initGame = function() {
    var info = {bullets:[], fishs:[], cannonType:1, scoreValue:0};
    var cannon = this.find("ui-cannon", true);
    var p = cannon.getPositionInWindow(); 
    cannon.center ={x: p.x + (cannon.w >> 1), y: p.y + (cannon.h >> 1)};    
    info.cannon = cannon;

    info.bottom = this.find("ui-image");
    var totalScore = this.find("ui-total-score", true);
    p = totalScore.getPositionInWindow(); 
    totalScore.center ={x: p.x + (totalScore.w >> 1), y: p.y + (totalScore.h >> 1)};    
    info.totalScore = totalScore;
    
    var bullet = this.find("ui-bullet").setVisible(false).setEnable(false);
    bullet.handleOnMoved = handleOnMoved;
    info.bullets.push(bullet);
    
    info.coin = this.find("ui-coin").setVisible(false);
    info.score = this.find("ui-score").setVisible(false);
    for(var i = 0; i < this.children.length; i++) {
        var iter = this.children[i];
        if(iter.name.indexOf("ui-fish") >= 0) {
            iter.handleOnMoved = handleOnMoved;
            iter.setEnable(false).setVisible(false);
            info.fishs.push(iter);
        }
    }
    info.timerID = setTimeout(makeFish, 1000);
    this.info = info;
}
//改变大炮类型
win.changeCannon = function(delta) {
    var info = this.info,cannon = info.cannon;
    info.cannonType = Math.max(1, Math.min(7, info.cannonType + delta));
    cannon.play("default"+info.cannonType, 100000);
}
//炮弹打中鱼时,炮弹变成网,鱼播放die动画,金币从炮弹处移动到总金币处。
win.onContacted = function(bullet, fish) {
    var info = this.info,cannon = info.cannon;
    bullet.setEnable(false).play("web"+info.cannonType, 1, function() {bullet.setVisible(false);});
    fish.setEnable(false).play("die", 1, function() {fish.setVisible(false)});
    info.scoreValue += 100;
    info.totalScore.setValue(info.scoreValue);
    info.coin.setVisible(true).animate({xStart:bullet.x, yStart:bullet.y, xEnd:info.totalScore.x, yEnd:info.totalScore.y-20});
}
//点击场景时,调整大炮位置,发射炮弹,大炮播放射击动画。
win.handleClick = function(point) {
    var info = this.info,cannon = info.cannon;
    if(this.targetShape != this.info.bottom) {
        var angle = Math.lineAngle(cannon.center, point) - 1.5 * Math.PI;
        cannon.setRotation(angle);
        var bullet = info.bullets.find(isObjInvisible);
        if(!bullet)  {
            bullet = win.dupChild("ui-bullet",0);
            info.bullets.push(bullet);
        }
        var x = cannon.center.x - (bullet.w >> 1), y = cannon.center.y - (bullet.h >> 1);
        bullet.setPosition(x, y).setRotation(angle).setVisible(true).setEnable(true).setV(5*Math.sin(angle),-5*Math.cos(angle));
        bullet.play("bullet"+info.cannonType);
        cannon.play("fire"+info.cannonType, 1);
        console.log(angle);
    }
}

this.initGame();

在场景的点击事件中:

this.handleClick(point);

在两个按钮中:

this.getWindow().changeCannon(-1);

好了,我们的捕鱼达人基本完成了。还有几个地方需要完善:1.射中多条鱼时分数加倍。2.鱼有不同的生命值,炮弹有不同的杀伤力。

呵河,这些问题留给读者动手去做吧,或许您就是下一个千万级游戏的开发者呢:)

参考资料:

https://github.com/drawapp8/gamebuilder/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTML5游戏实战(2):90行代码实现捕鱼达人 的相关文章

  • unity中创建询问弹出窗口

    在开发过程中进程会遇到需要弹出一个窗口询问用户是否进行的操作 今天就来制作一个这样弹出窗口 然后根据弹出窗口的选择内容不同进行不同的操作 本例中主要是为了删除一个数据 而在删除数据操作前需要得到用户的一个确认操作 这里面主要用到了Notif
  • Unity学习笔记(一)—— 基础知识

    一 基础知识 1 开发团队组成 2 unity特点 图形界面 所见即所得 入门简单 支持C 比OC C 更友好 js 国内外资源丰富 因为使用的人多 跨平台性好 PC端 移动端等 对VR AR的支持最完善 3 成功案例 游戏 炉石传说 神庙
  • 俄罗斯方块游戏(C语言)

    简介 俄罗斯方块 Tetris 是一款经典的游戏 下面是用C语言实现俄罗斯方块的示例代码 code include
  • Unity打包WebGL的优化常用操作?

    1 贴图部分优化 如果贴图格式时2048 在不影响画面效果的情况下 改成1024或者5 12 还可以缩小包体 2 压缩和解压缩问题 WebGL打包的时候分三种压缩情况 gzip 比Brotli文件打 但打包快 http和https都支持 B
  • 基于java的飞机大战游戏系统设计与实现

    基于java的飞机大战游戏系统设计与实现 I 引言 A 研究背景和动机 背景 随着现代游戏产业的不断发展 传统的飞行射击游戏已经无法满足玩家对新颖 刺激的需求 因此 设计一个基于Java的飞机大战游戏系统成为了游戏开发人员们的共同目标 动机
  • 《开箱元宇宙》:Madballs 解锁炫酷新境界,人物化身系列大卖

    你是否曾想过 元宇宙是如何融入世界上最具代表性的品牌和名人的战略中的 在本期的 开箱元宇宙 系列中 我们与 Madballs 的战略顾问 Derek Roberto 一起聊聊 Madballs 如何在 90 分钟内售罄 2 000 个人物化
  • C++ 游戏服务器方向需要多少功底?

    这篇文章是回答一位知友的提问 现在大二了马上升大三 就读于一个很垫底的211 专业是计算机相关的 但是对本专业内容不感兴趣 希望能从事c 后端的工作 对游戏比较有兴趣 但又不知道需要哪方面的知识 希望各位能给出一个客观的评价或者批评 帮忙指
  • 运行游戏找不到x3daudio1_7.dll怎么解决?教你如何快速修复的教程

    在计算机使用过程中 我们经常会遇到一些错误提示 其中之一就是 x3daudio1 7 dll丢失 这个错误提示可能让我们感到困惑和烦恼 但是不用担心 本文将为您介绍x3daudio1 7 dll丢失的原因以及五种修复方法 帮助您解决这个问题
  • 华为OD机试真题-游戏分组-2023年OD统一考试(C卷)

    题目描述 部门准备举办一场王者荣耀表演赛 有10名游戏爱好者参与 分为两队 每队5人 每位参与者都有一个评分 代表着他的游戏水平 为了表演赛尽可能精彩 我们需要把10名参赛者分为实力尽量相近的两队 一队的实力可以表示为这一队5名队员的评分总
  • 游戏弹窗找不到emp.dll怎么办?分享5个靠谱的解决方法

    在现代的游戏世界中 我们经常会遇到各种各样的问题 其中 最常见的问题之一就是 无法找到emp dll 或 emp dll丢失 那么 emp dll到底是什么 它有什么作用 为什么会出现丢失的情况呢 不用担心 本文将从这几个方面进行详细解析
  • 【Unity】如何让Unity程序一打开就运行命令行命令

    背景 Unity程序有时依赖于某些服务去实现一些功能 此时可能需要类似打开程序就自动运行Windows命令行命令的功能 方法 using UnityEngine using System Diagnostics using System T
  • 【转载】【Unity】WebSocket通信

    1 前言 Unity客户端常用的与服务器通信的方式有socket http webSocket 本文主要实现一个简单的WebSocket通信案例 包含客户端 服务器 实现了两端的通信以及客户端向服务器发送关闭连接请求的功能 实现上没有使用U
  • 计算机提示vcruntime140.dll丢失的解决方法,多种修复教程分享

    vcruntime140 dll是一个非常重要的动态链接库文件 它包含了许多运行时的函数和类 然而 有时候我们可能会遇到vcruntime140 dll无法继续执行代码的问题 这会给我们带来很大的困扰 那么 这个问题是什么原因导致的呢 又应
  • 如何有效获取APP新增用户

    在提升APP用户获取效果方面 有几个关键策略可以考虑 市场定位与目标用户明确 在推广过程中 确保清晰地了解你的目标用户是谁 以便有针对性地开展推广活动 对用户的需求和偏好有深入了解 可以更好地制定吸引用户的策略 引人入胜的营销策略 设计有吸
  • 盘点第三方支付行业中一些“专用术语”

    每个行业都有自己的行业术语 在官方场合被称为 术语 如果你是支付行业的新手 或者正在努力深入了解这个复杂但充满机遇的领域 那么掌握行业术语就是打开这扇门的关键 支付系统的需求文档和技术方案文档都充斥着专业词汇和行业术语 有些词汇容易理解 有
  • 基于java的扫雷游戏系统设计与实现

    基于java的扫雷游戏系统设计与实现 I 引言 A 研究背景和动机 扫雷游戏是一种经典的益智游戏 由于其简单易学 规则简单 玩法多样等特点 深受广大游戏爱好者的喜爱 但是 现有的扫雷游戏系统往往存在着游戏难度不均衡 游戏时间过长 游戏规则不
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之角色选择一

    进入游戏后 我们经常会进入角色选择的界面 通常是左右两个按钮可以更改角色供玩家选择 对于这种界面我们通常使用数据持久化将角色信息存储起来 接下来的笔记中 我将使用自带的数据持久化系统对其进行操作 实现角色的选择页面 后续会更新xml系列的文
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接
  • 申泰勇教练的独家人物化身系列即将登陆 The Sandbox

    申泰勇 Shin Tae yong 教练是足球界的传奇人物 他来到 The Sandbox 推出了自己的专属人物化身系列 作为前 K 联赛中场球员和印尼队取得历史性成就的幕后教练 他的传奇经历现在已经影响到了虚拟世界 向过去 现在和未来致敬

随机推荐

  • notepad++ 快捷键

    Notepad 绝对是windows下进行程序编辑的神器之一 要更快速的使用以媲美VIM 必须灵活掌握它的快捷键 下面对notepad 默认的快捷键做个整理 其中有颜色的为常用招数 1 文件相关 快捷键 动作定义 Ctrl O 打开文件 C
  • (20200720已解决)_pickle.UnpicklingError: A load persistent id instruction was encountered,

    but no persistent load function was specified 问题描述 如题 提取pickle数据 解决方案 直接解释是因为生成pickle文件的过程中使用了persistent load 但是读取过程中没有提
  • 云原生之使用docker部署mongodb数据库

    云原生之使用docker部署mongodb数据库 一 检查系统版本 二 检查docker状态 三 检查docker版本 四 下载mongodb镜像 五 创建mongodb容器 1 创建数据目录 2 创建mongodb容器 3 查看mongo
  • Python中的sns.set_palette函数是一个非常有用的函数,它可以设置Seaborn库中的调色板。这个函数允许用户设置颜色列表,并将它们应用于所选的...

    Python中的sns set palette函数是一个非常有用的函数 它可以设置Seaborn库中的调色板 这个函数允许用户设置颜色列表 并将它们应用于所选的绘图 在这篇文章中 我将详细介绍sns set palette函数的使用方法 并
  • STM32外设系列—L298N

    文章目录 一 L298N简介 二 L298N电路图 三 L298N使用方法 四 L298N驱动电机实例 4 1 麦克纳姆轮简介 4 2 定时器PWM配置 4 3 智能车行驶控制 五 拓展应用 一 L298N简介 L298N是SGS公司生产的
  • 强化学习 优势函数(Advantage Function)

    目录 什么是优势函数 归一化 激活函数等学习问题 为什么要使用优势函数 常见的优势函数 什么是优势函数 优势函数表达在状态s下 某动作a相对于平均而言的优势 从数量关系来看 就是随机变量相对均值的偏差 使用优势函数是深度强化学习极其重要的一
  • 用汇编语言实现结构体的输入和保存

    COUNT EQU 1 ALL INPUT MACRO STRING NUM FUNCTION MOV DX OFFSET STRING MOV AH 9H INT 21H MOV DI OFFSET INFO NUM MOV AX SIZ
  • 软件工程思考(四)

    Prototyping 在生成产品以前 一般需要进行原型验证 可以得到遇到的困难以及用户体验 需要增加的功能进行加入新的东西 原型验证中 平台选择 需求清晰化以及用户接口这些都是未知的 所以有较高的风险 原型验证中UI设计可以使用纸质或者是
  • 01_2_数字基带传输及其频谱特性

    一 数字基带信号的表示 g t g t g t 是一个基本的脉冲 有不同形状 a n
  • python 播放自定义的语句 MP3文件

    使用python播放自定义文本 比如播放你想说的话 运行以下PY代码 就会在项目路径下产生一个MP3文件 里面循环播放你写自定义语句 from PyQt5 QtCore import QUrl from PyQt5 import QtMul
  • Unikernel不适合生产环境

    最近我犯了个错 在Twitter上语气激昂的问是否该讲讲为什么unikernel不适合用在生产环境 结果响应十分强烈 有的人感觉unikernel走错方向了 在寻找支持这种观点的细节 有的人是unikernel的支持者 也很想知道反对uni
  • R-CNN系列论文综述

    本文首发自 CSDN 上几期我们讲过目标检测 One Stage 的代表 YOLOv3 本来这一期是打算写 SSD One Stage 的另一个代表 的 发现 SSD 其中涉及的知识是从 R CNN Two Stage 来的 故此 这一期我
  • 问题 D: 稀疏矩阵类型判断

    题目描述 输入一个稀疏矩阵 输出其类型 类型包括 上三角 对角线及其右上方的元素非0 其它元素为0 下三角 对角线及其左下方的元素非0 其它元素为0 对称 沿对角线对称的元素非0且相等 空矩阵 所有元素都为0 其它为普通矩阵 输入 输入包括
  • SpringBoot项目搭建并以打jar包方式部署运行

    一 项目搭建 1 去springBoot官网下载demo SpringBoot官网 https start spring io 2 点击Generate Project下载demo并将其以maven方式导入到eclipse中 3 选择要集成
  • axios用headers传参,设置请求头token

    不知道该怎么描述我这个问题 之前有听一个前端经理说 使用http协议的时候要用headers传参 新公司就是使用http协议的 在vue项目中 使用了axios 要根据header里的token判断用户是否登录 如上图 一开始的理解为是像d
  • 前段技术加html+css+JS

    前段技术加html css JS html 负责页面的结构 语义 网页制作语言 不是编程语言 css 负责页面的美化 样式 js 增加交互或特效 HTML基本知识点 HTML含义 html超文本标记语言 通过标签进行语义化描述 超文本 就是
  • No implementation found for int com.baidu.mapsdkplatform.comjni.tools.JNITools.initClass(java.lang.O

    今天又有一个历史项目需要维护 发现百度地图只显示网格 没有图像出来 感觉可能是签名问题 但是下载来的代码中只有那一个签名 所以干脆把百度地图的东西都替换掉 替换完一运行 直接崩溃了 E NativeLoader found libBaidu
  • 【Unity灯光与渲染技术】Global Illumination全局光照

    本系列主要参考Unity灯光与渲染技术教程Unity Lighting And Rendering 同时会加上一点个人实践过程和理解 分割线 这篇文章主要讲全局光照 在看教程的时候就有一个点不是很理解 就是作者开启物体的static这个选项
  • 字母大小写转换(python实现)

    python实现大小写转换主要用lower和upper函数 lower 将字符串中的所有大写字母转化为小写字母 upper 将字符串中的所有小写字母转化为大写字母 s input 输入一个字符串 print s upper 输入 i lov
  • HTML5游戏实战(2):90行代码实现捕鱼达人

    捕鱼达人是一款非常流行的游戏 几年里赚取了数以千万的收入 这里借用它来介绍一下用Gamebuilder CanTK开发游戏的方法 其实赚钱的游戏未必技术就很难 今天我们就仅用90来行代码来实现这个游戏 CanTK Canvas ToolKi