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行代码实现捕鱼达人 的相关文章

  • align-content 设置多行下的子元素排列方式 代码和图片展示

    align content 适用于 换行 多行 的情况下 单行无效 可以设置上对齐 居中拉伸和平均分配剩余空间等属性值 属性值 flex start 默认值 在侧轴头部开始排列 flex end 在侧轴尾部开始排列 center 在侧轴中间
  • 在聚会中常玩数七的游戏,七的倍数和带有七的数字都不能说,比如14,27,28。请找出1~100的不能说的数字。...

    利用ES5的filter高阶函数来实现 var arr 1 2 3 4 5 6 7 17 27 21 22 28 100 r arr filter function x return x 10 7 x 7 0 alert r 7 14 17
  • HTML5学习(三):布局标签、列表、超链接和id

    1 布局标签 header表示网页的头部 页眉 main表示网页的主体部分 一个页面中只会有一个main footer表示网页的底部 页脚 nav表示网页中的导航 aside和主体相关的其他内容 侧边栏 article表示一个独立的文章 s
  • html创建添加地图(超简单)

    1 打开百度地图创建平台 百度地图创建平台 2 根据个人需求改就行了 可加标注 3 点击获取代码 复制下来就可以用了 4 个人用的是HBulider 复制到里面可直接用了 如果有文字显示问题 把编码改成utf 8就行了 5 地图控件位置在网
  • 基于java的飞机大战游戏系统设计与实现

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

    你是否曾想过 元宇宙是如何融入世界上最具代表性的品牌和名人的战略中的 在本期的 开箱元宇宙 系列中 我们与 Madballs 的战略顾问 Derek Roberto 一起聊聊 Madballs 如何在 90 分钟内售罄 2 000 个人物化
  • 基于Python手把手教你实现flappy bird游戏

    目录 前言 开始前的准备工作 进入正题 结束语 前言 想必玩过游戏的都知道 Flappy Bird是一款简单却富有挑战性的经典的小鸟飞行游戏 让许多玩家为之痴迷 而作为开发者 那肯定要通过技术手段来再做一遍这款经典游戏 那么本文就来通过万能
  • 探索元宇宙链游戏:一场数字世界的奇妙融合

    随着互联网的飞速发展 以及人们不断对互动娱乐体验的要求提高 元宇宙渐渐成为人们追求的目标 而区块链技术的出现给元宇宙链游开发带来了新的机遇和挑战 一 元宇宙链游定义 元宇宙链游全称为基于区块链技术的元宇宙游戏 是一种新型的网络互动娱乐形式
  • 运行游戏找不到x3daudio1_7.dll怎么解决?教你如何快速修复的教程

    在计算机使用过程中 我们经常会遇到一些错误提示 其中之一就是 x3daudio1 7 dll丢失 这个错误提示可能让我们感到困惑和烦恼 但是不用担心 本文将为您介绍x3daudio1 7 dll丢失的原因以及五种修复方法 帮助您解决这个问题
  • 基于html5的国家历史文物网站的设计与实现-计算机毕业设计源码63653

    目 录 摘 要 Abstract 第 1 章
  • 坦克大战(二)

    欢迎来到程序小院 坦克大战 二 玩法 键盘 A W S D 键来控制方向 空格键发射子弹 N 下一关 P 上一关 Enter 开始 赶紧去闯关吧 开始游戏 https www ormcc com play gameStart 221 htm
  • 坦克大战(二)

    欢迎来到程序小院 坦克大战 二 玩法 键盘 A W S D 键来控制方向 空格键发射子弹 N 下一关 P 上一关 Enter 开始 赶紧去闯关吧 开始游戏 https www ormcc com play gameStart 221 htm
  • 如何有效获取APP新增用户

    在提升APP用户获取效果方面 有几个关键策略可以考虑 市场定位与目标用户明确 在推广过程中 确保清晰地了解你的目标用户是谁 以便有针对性地开展推广活动 对用户的需求和偏好有深入了解 可以更好地制定吸引用户的策略 引人入胜的营销策略 设计有吸
  • 计算机提示vcruntime140.dll丢失的解决方法,多种修复教程分享

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

    文章目录 前言 一 指数雾 雾效因子 1 FOG EXP 2 FOG EXP2 二 MixFog 1 ComputeFogIntensity 雾效强度计算 2 lerp fogColor fragColor fogIntensity 雾效颜
  • 第8章 多媒体嵌入

    学习目标 了解视频 音频嵌入技术 能够总结HTML5视频 音频嵌入技术的优点 了解常用的视频文件格式和音频文件格式 能够归纳HTML5支持的视频和音频格式 掌握HTML5中视频的嵌入方法 能够在HTML5页面中添加视频文件 掌握HTML5中
  • 游戏被攻击了要怎么办

    有客户反馈刚上线新款游戏 没两天就被攻击了 导致用户无法登录 来咨询到我们这边能不能帮他解决 今天就来分享下 怎么预防游戏攻击和已经被攻击的游戏服务器该怎么处理 服务器不管是个人还是企业 被攻击的都有 在所难免 特别是新上线时候要承受住外来
  • 游戏开发创建操作之玩家信息系统的建立

    游戏一般都需要玩家信息系统 那么我们应该如何搭建玩家信息系统 接下来我将展示一种简单的方法 完整代码如下 using System Collections using System Collections Generic using Uni
  • 游戏开发常见操作梳理系列之——玩家信息的显示系统

    在游戏中 有不少游戏在左上角会出现玩家的头像和等级以及血量 这就是玩家的信息显示系统 那么这些是如何制作的呢 接下来我将讲讲代码的操作 其它操作我会在其它笔记中一一说明 敬请期待 信息的显示相当简单就是控制一些UI 然后在其它系统里面填写相
  • 游戏开发之常见操作梳理——武器装备商店系统(NGUI版)

    游戏开发中经常出现武器商店 接下来为你们带来武器装备商店系统的具体解决办法 后续出UGUI Json版本 敬请期待 武器道具的具体逻辑 using System Collections using System Collections Ge

随机推荐

  • 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