注:文章内容较长

一些回忆:

本人目前是大一新生,这也是我发的第一篇文章,还望多多指教。小时候非常喜欢4399和7k7k等小游戏平台,也不玩页游,于是小学周末放假,便与三两朋友,就着一台破电脑挨个试玩Flash游戏,非常有趣。之后学校开设flash动画的第二课堂,就果断参加,逐渐熟悉矢量图绘制(但绘画基础不牢靠)。之后又在图书馆找到一本用flash内置的ActionScript开发游戏的书,非常激动,连续借了好几个月,但由于不熟悉三角函数等基础知识,很多代码都是照着码上去的,但看着游戏跑起来,还是非常开心(个人认为,比隔壁Scratch开心一百倍!)。

应该就是这本,《ActionScript3.0游戏编程》

对Flash的一些个人看法

从最初的Flash10,到Flash CS5,再到Flash CS6,最后到现在的Adobe Animate 2022,每次更新换代,都把它们拖到桌面上相同的位置,像是专门留了把椅子(我几乎在与这款软件一起成长......)。从单纯的绘画,再到动画,再到脚本的编程,自己也在平日里一点一点地学习。要说一点看法没有,那是不可能滴。以下便是一点点个人看法,由于对其他软件接触不深,可能会有偏颇。

  • Flash界面清爽,既适合绘画,也适合在帧上直接写下脚本,美术和程序在我(年幼无知的)眼里结合得相当不错。且在学习面向对象编程的时候,在每一个影片剪辑中都可以编写相应的类,每个对象直接拖动、命名,非常地形象可视;且在界面布局方面,既可以直接在舞台上编辑,也可以写脚本批量控制,在我看来非常方便。

  • Flash CS5更新了绑定骨骼功能。对于无精力画逐帧动画的人来说,真的非常好用!

  • Adobe Animate更新了摄像头功能。终于,在有了摄像头以后,一些视角跟踪的游戏可以实现了!

  • 但也有一些遗憾,比如基于HTML Canvas的flash文档,事实上,直接使用js开发,搭配canvas的拓展组件或许会更方便;又比如相关参考资料不多,而且打开偏慢。这次游戏制作主要看的资料不过这两个:Animate中的摄像头,Adobe ActionScript3 API参考,有些功能,如Vector等的使用,还要自己摸索,或者求助于隔壁javascript的相关问题。

开发记录

开发草案(或者叫策划?)

1. 故事构思

7k7kRaze2讲述了人类特种部队(Raze)抵抗异形入侵的故事.在这个过程中,主角需要化解丧尸,失控机器人等一系列灾难,最后与异形抢夺紫色能石blabla现在异形控制了赛博城里随处可见的携带激光武器的无人机,我们的Raze要在复杂的城市地图中将它们清扫干净

2. 素材绘制:
  • 动态漫剧情介绍

  • 游戏界面和菜单游戏场景设计:后景、动态元素、近景游戏地图设计玩家骨骼动画敌人动画枪械子弹

3.核心逻辑:平台动作游戏
  • 玩家操作:

  • a和d键:摁下时设置x轴左右移动速度,抬起时结束移动。注意结束时动画应回到第一帧暂停。

  • w:与地面接触,触发一段跳,设置y轴向上速度,在跳起或腾空时再按下可触发二段跳。

  • s:触发下蹲动作,此时无法左右移动

  • 摄像头跟踪玩家以及抖动特效:

  • 需调用库:fl.VirtualCamera;

  • 追踪方法:cameraObj.pinCameraToObject(getChildByName("InstanceName"), offsetx,offsety);其中offset可设置爆炸时抖动的特效,搭配setTint实现色调变白

  • 碰撞检测:高级检测方式有两种,位图检测(bitmap,精细度高,用于复杂图形,且像素点不能太多)

网格检测(grid,更迭次数少,用于大量图形检测);但我都不会,本次地图与玩家碰撞就用矩形碰检吧哈哈哈。只需要利用速度提前判断下一帧的位置是否与某墙壁相碰,是则下一帧位置与墙贴合,再根据需要编写贴合、反弹、消失等行为

  • 子弹运动逻辑:由易到难

  • 线性激光类武器:子弹线形,无延迟,只需要判断该射线与地图矩形的碰撞位置,并在该点截断激光即可

  • 反弹激光:在原有激光的基础上碰墙反弹,可以使用队列描述轨迹

  • 普通球型子弹:速度慢,轨迹为抛物线,碰墙反弹。

  • 范围型武器:碰墙爆炸,产生范围伤害,使用队列描述尾迹

  • 跟踪类子弹:速度偏慢,逻辑为追逐行为。

  • 弹刀特性:玩家抽出用激光刀划出优美(X)的圆,使得敌人子弹变为自己的子弹,用中学知识即可计算出反射向量。

4.游戏界面跳转安排:略

开发过程

1.坑:坐标系变换。若直接获取影片剪辑中的子元件坐标(如士兵对象中的子对象枪的坐标),得到的是它相对于容器(即士兵对象原点,通常是左上角)的坐标。若要得到相对于舞台的坐标,需要用localToGlobal方法:
var gunPoint:Point = (容器)player.localToGlobal
(new Point((子对象x)player.gun.x , (子对象x)player.gun.y) ));

且如果存在对象嵌套(如player.gun.shootingpoint),只需要用一次该方法即可转化为舞台坐标系下的坐标。

但是,当启用摄像头时,舞台会跟踪玩家移动,不是一个静止的参考系。因此,需要再将舞台坐标,转化为相对于场景中任意一个对象(通常在原点位置放一个点对象,可命名为basePoint,专门用于定位)的坐标:

var realGunPoint:Point = basePoint.globalToLocal(gunPoint);
2. 坑:使用脚本控制与原动画的冲突。像Raze游戏一样,需要实现让玩家的头、手和枪都实时朝向鼠标的功能,所以需要实时更改它们的rotation属性。但这时,它们就不会跟随原来身体一起下蹲了!出现了经典的分头行动。。。。。。尽管动画改变的只是x和y属性,并没有动用rotation,但脚本好像“接管”了对它们的控制。。。。。。最后苦思无果,只能用很笨的方法,即在脚本上再跟随帧数,控制它们的x,y,实现下蹲

正在被敌机包围中

3.有趣的环节:敌人行为逻辑的设计
  • 生成点在楼顶,若与玩家距离小于开火区,用线段检测中间是否有障碍阻隔,无则发射激光

  • 一开始没用寻路,敌人就朝着玩家前进,遇到墙往回弹一下,沿切向走。为了不被玩家轻易打死,会在距离小于一定范围时缓慢绕行。但这样敌人还是容易被墙卡住,不会主动到身旁。

  • 所以用astar寻路算法,首先用二维网格划分场景,其中考虑敌机身长体宽,将障碍物的边界作扩增处理,如果点在矩形内,则将该处格点标为1,其余可走路径,标为0

  • 接着设计节点类,存储当前坐标、父节点、出发点到当前点的代价h,曼哈顿距离(四个移动方向)或欧几里得距离(八个移动方向)g,设置评估方法f=h+g

class Node {private var now: Point;private var dad: Node = null;private var g: uint;private var h: uint;//构造函数,不一定有父节点public function Node(nowpoint: Point, target: Point) {this.now = nowpoint;this.h = 0;this.calg(target);}public function seth(pare: Node, cost: uint):void {this.dad = pare;this.h = this.dad.h + cost;}public function getdad():Node{return this.dad;}public function F(): uint {return this.g + this.h;}public function H(): uint {return this.h;}public function P(): Point {return this.now;}//八个方向走,计算欧几里得距离,//四个方向则计算曼哈顿距离private function calg(target: Point) {var disx:uint = Math.abs(target.x - this.now.x);var disy:uint = Math.abs(target.y - this.now.y);//this.g = disx+disy;this.g = (disx>disy)?((disx-disy)*10+disx*14):((disy-disx)*10+disy*14);}}
  • 最后编写astar算法,设置open和close两个数组,每次在open数组中选取f最小的节点展开并踢到close数组中。遍历展开的4个或8个节点:若已在open中,则判断新展开节点从出发点到达此处的代价是否更小,在open中保留代价更小的那个节点;若在close中,表示已经走过,不保留这个展开节点;否则这个节点是新的,加入open中。这样逐步展开,直到找到终点或没有可以展开的节点为止。

public var route: Array;//存储结果
private const stepx:Array = [-1,0,0,1,1,1,-1,-1];//每一步可以沿八个方向展开
private const stepy:Array = [0,-1,1,0,1,-1,1,-1];//查询是否到过,针对closelist当中的节点
private function iswent(list:Array,tx:int,ty:int):Boolean{for(var q=0;q<list.length;q++){if(int(list[q].x) == tx && int(list[q].y) == ty){//trace("went!",tx,ty);return true;}}return false;
}//查询是否展开过且自动更新,针对openlist当中的节点
private function isopen(nodelist:Array,newnode:Node):Boolean{for(var q=0;q<nodelist.length;q++){if(nodelist[q].P().x == newnode.P().x &&nodelist[q].P().y == newnode.P().y){if(nodelist[q].H() > newnode.H()) nodelist[q] = newnode;return true;}}return false;
}//维持一个优先队列,f小的放前面
private function insert(list:Array,newnode:Node):void{var index:uint=0;while(index<list.length && list[index].F()<newnode.F()) index++;list.insertAt(index,newnode);
}//每个敌人的astar每N秒一更新,将更新route
public function astar(grid: Array, sta: Point, end: Point):void{//越界判定if(sta.x<0 || sta.x>=grid[0].length ||sta.y<0 || sta.y>=grid.length ||end.x<0 || end.x>=grid[0].length ||end.y<0 || end.y>=grid.length){return;}this.route = new Array();//存储目前刚展开的节点,即开始列表var que: Array = new Array();que[0] = new Node(sta,end);//存储关闭节点,即关闭列表var close:Array = new Array();do{//选择F最小的节点展开,在优先对列中只需取第一个元素,并放入关闭节点中,只保存其坐标var tnode:Node = que.shift();close.push(tnode.P());//打开邻近节点                for(var q=0;q<this.stepx.length;q++){var nowx = tnode.P().x+stepx[q];var nowy = tnode.P().y+stepy[q];//筛选可以展开的节点,不越界,无障碍,未走过,未展开if(nowx>=0 && nowx<grid[0].length&& nowy>=0 && nowy<grid.length&& grid[nowy][nowx] == false&& !iswent(close,nowx,nowy)&& !isopen(que,tnode)){//trace("open!",nowx,nowy);//终点判定,开始回溯路径,路径倒序存储,最后reverseif(nowx == end.x && nowy == end.y){this.route.push(end);this.route.push(tnode.P());while(tnode.getdad() != null){tnode = tnode.getdad();this.route.push(tnode.P());}this.route.reverse();//强制退出;que = [];break;}var temp:Node = new Node(new Point(nowx,nowy),end);temp.seth(tnode,(q<=3 ? 10:14));//真·插入排序insert(que,temp);}}}while(que.length != 0);
}

最后,每帧都将route中的第一个节点当成敌机的目标,到达附近后shift()删除第一个节点,敌人便可以一直追着玩家满地图跑了

每过几秒,敌人的路径就会指引到玩家身边的节点

写在最后

使用多年,个人还是很喜欢用Animate的。希望能向各位读者大佬学习,热情不减,走向一个又一个未知的领域!

AniamtexActionScript3.0游戏复刻记录相关推荐

  1. linux 游戏 复刻,魔法门复刻手游官网版-魔法门复刻下载v4.00.9-Linux公社

    魔法门复刻是一款具有超级震撼的世界画面设计的手机游戏.黑暗的魔幻世界风,暗黑的人物形象设计,以及酷炫的游戏战斗场景,都将游戏打造得非常的暗黑系精致.并且游戏里面的种族战争,阵营设计非常的全面,< ...

  2. linux 游戏 复刻,用 PICO-8 复刻 Infinite Loop 游戏

    前言 第一次使用 PICO-8 开发游戏,虽然跟 Unity3d,cocos2d 比起来 PICO-8实在是简陋,但是用起来却十分的令人着迷.8bit 复古风的 PICO-8 的限制十分的多,比如 1 ...

  3. [技美CG]Unity3D复刻UnityShader 之 ShaderToy - Bubbles

    Unity3D复刻UnityShader 之 ShaderToy - Bubbles 背景: 官方地址/参考资料: ShaderToy-Bubbles原始代码: Unity复刻开始 核心显示类: 核心 ...

  4. 用vue3+pixijs复刻童年记忆里的游戏-猎鸭季节

    大厂技术  坚持周更  精选好文 前言 本期将用vue3与pixijs复刻出童年在小霸王里面玩的游戏-猎鸭季节,当初玩它需要光线枪才行,非常不好瞄准,每当打中鸭子就非常激动,打不中就会有收到狗子的嘲笑 ...

  5. fc坦克大战游戏完美复刻

    文章目录 一. 介绍 二. 制作基本物体 三. 控制玩家坦克移动.转向 四. 子弹脚本.爆炸脚本 五. 敌人AI寻路算法 六. 坦克生成点脚本 七. 用链表实例化地图 八. 玩家游戏控制器脚本 九. ...

  6. python带你成功复刻热门手机游戏——飞翔的小鸟

    前言 大家早好.午好.晚好吖 ❤ ~欢迎光临本文章 飞翔的小鸟(游戏英文名:Flappy Bird) 一款由越南独立开发者开发的手机游戏,是之前非常流行的一款手机游戏 小游戏目标:让小鸟穿过管子,不要 ...

  7. C语言初学者复刻经典扫雷小游戏(图形界面,非黑白窗口)(含源码)

    注:除计时器和剩余雷数显示外,其他功能完美还原. 目录 一.程序演示 二.程序信息 1.基础信息 2.前言 3.所需文件 三.代码解析 1.头文件 2.变量声明 3.随机生成雷 4.生成雷位置矩阵 5 ...

  8. 游戏开发之路之“复刻或升级游戏”---地球末日生存

    复刻之路-第一周.第二周 〇. 初始游戏计划 1. 人员安排 2. 内容安排 3. 计划安排 初期: 中期: 一. 开发进度 1. 第一周 - 学习背包系统和成就系统原理 - 画万能Sprite 2. ...

  9. java奇缘幻境_奇缘幻境按键机版app下载-奇缘幻境复刻版安卓客户端v1.1.0 - 找游戏手游网...

    奇缘幻境按键机版下载是一款角色扮演类修仙手游.游戏中玩家可以自由的选择门派,每个门派都有不同的武学任你选择.游戏内容十分丰富,玩法多样. 游戏介绍: 奇缘幻境按键机版下载,功能机有史以来最经典的RPG ...

最新文章

  1. 从浏览器发展史读懂user-agent
  2. redis 突然大量逐出导致读写请求block
  3. ASP.NET AJAX(开发代号:Atlas)的相关问题请在本帖中提出
  4. 用Java Servlets代替CGI
  5. 技术面试官的一些建议
  6. ASP.NET页面之间传值的方式之Cookie(个人整理)
  7. 滴滴接盘小蓝单车,押金问题谁来负责?
  8. MySQL(3)-----DML数据库操作(上)
  9. 面试必备项目之从零开发大众点评后端(SSM)
  10. FileZilla服务器乱码问题
  11. Python数据分析之智联招聘职位分析完整项目(数据爬取,数据分析,数据可视化)
  12. DNK开发—Eclipse环境变量配置
  13. Zynga和Unity:独家奖励广告
  14. WPS网盘怎么显示在我的电脑里?
  15. JDBC基础理解与实现操作
  16. Python求两个圆的交点坐标或三个圆的交点坐标
  17. 单软多硬使用说明(展讯平台)
  18. 求出一个数所有的因数
  19. jQuery跳房子插件hopscotch
  20. 项目管理常见的输入输出

热门文章

  1. Nutanix荣膺 “超融合基础架构领导者” 称号
  2. 根据 近地点、远地点、倾角、自转周期 计算卫星轨道
  3. 电池SOC仿真系列-基于UKF算法的电池SOC估算研究
  4. 国土调查无人机举证系统
  5. 计算机网络和综合布线的关系,综合布线与计算机网络.ppt
  6. 管家婆辉煌版提示:嘚瑟反馈率F 请联系任我行软件股份公司或当地合法代理,有后门?
  7. Python 惰性计算
  8. 非接触式射频读卡器 M1读卡,支持USB,ISO14443A/B,可读二代证ID
  9. 【代码审计】YzmCMS_PHP_v3.6 代码执行漏洞分析
  10. Linux内核教程(1) - 道路千万条,调试最重要