8.弹幕系统
弹幕系统概述:
弹幕系统的设计体现了射击游戏的基本要素,玩家要在敌人放出的大量子弹(弹幕)的细小空隙间闪避,能在玩家闪躲弹幕的时候给玩家带来快感,接近满屏的子弹,增加了对玩家的视觉冲击力。
弹幕系统原理:
每一个敌机都持有一个弹幕实例,每个弹幕实例中包含多个子弹实例,通过配置弹幕的属性,使每个子弹实例在轨迹管理器的作用下,形成一种有规律性的直线运动,在视觉上给玩家展现出弹幕的效果。如图8-1所示。

图8-1
实现方法:
步骤1:
子弹类,定义子弹的属性和借口。
04 |
public void CreateActor () |
06 |
_obj = ActorManager.CreateFromTemplate( @"asset:bullet01.template" , false ); |
11 |
public void ActiveObj (Vector2 startPos) |
14 |
if (_obj.GetChildCount()>0) |
16 |
_obj.GetChild(0).Active(); |
19 |
_obj.WorldPosition = new Vector3 (startPos.X,startPos.Y,2.0f); |
23 |
public void DeactiveObj () |
26 |
if (_obj.GetChildCount()>0) |
28 |
_obj.GetChild(0).Deactive(); |
31 |
private Actor _obj = new Actor(); |
33 |
private UInt32 _target_id; |
34 |
private Vector2 _startPos; |
35 |
private bool _isShooted = false ; |
步骤2:
配置弹幕发射子弹的属性。
04 |
public void ShootBullet ( float elapsedTime, Vector3 pos) |
07 |
if (timer >= _shoot_interval && _needshoot_id <= (Bullets.Count - 1)) |
09 |
Vector2 posV2 = new Vector2(pos.X,pos.Y); |
10 |
Bullets[_needshoot_id].ActiveObj(posV2); |
11 |
Bullets[_needshoot_id].SetShooted( true ); |
16 |
private UInt32 _obj_id; |
17 |
private float _start_speed; |
18 |
private float _accel_speed; |
19 |
private float _shoot_interval; |
20 |
private float _shoot_direction; |
21 |
private float _direction_offset; |
22 |
private List< Bullet> Bullets; |
23 |
private TrajectoryType _tt ; |
24 |
private float timer = 0.0f; |
25 |
private int _needshoot_id = 0; |
步骤3:
设计弹幕管理器,管理每一个弹幕实例的发射。
01 |
public class BarrageMgr |
04 |
public bool AskForBullets ( int count, List< Bullet> bullets, Actor owner) |
06 |
if (ReloadBullet.Count == 0) |
11 |
if (count >= ReloadBullet.Count) |
13 |
count = ReloadBullet.Count; |
16 |
for ( int i = 0; i < count; i++) |
18 |
ReloadBullet[i].DeactiveObj(); |
19 |
Vector2 pos = new Vector2(owner.WorldPosition.X,owner.WorldPosition.Y); |
21 |
ReloadBullet[i].setPos(pos); |
22 |
bullets.Add(ReloadBullet[i]); |
25 |
ReloadBullet.RemoveRange(0,count); |
29 |
public void DealTrajectory (Barrage barrage, float elapsedTime) |
31 |
_trajectoryMgr.MoveBarrage(barrage,elapsedTime); |
34 |
public void Tick( float elapsedTime) |
36 |
foreach (KeyValuePair< uint ,Barrage> pair in _barrageDict) |
39 |
Barrage barrage = pair.Value; |
41 |
DealTrajectory(barrage,elapsedTime); |
42 |
barrage.DestroyBullet(); |
43 |
if (!barrage.IsOwnerActive() && barrage.IsAllBulletsDeactive()) |
48 |
Debug.Dbgout( _barrageDict.Count.ToString() ); |
步骤4:
设计轨迹管理器,使子弹形成一种有规律性的直线运动。
01 |
public class Trajectory |
04 |
public static Vector2 GoStraight(Vector2 start_pos, float direction, |
05 |
float start_speed, float accel_speed, float use_time, out Vector2 pos) |
07 |
float angle = direction * ( float )Math.PI / 180.0f; |
08 |
float seconds = ( float )use_time; |
09 |
float move_length = start_speed * seconds + accel_speed * seconds * seconds / 2.0f; |
10 |
pos.X = move_length * ( float )Math.Cos(angle) + start_pos.X; |
11 |
pos.Y = move_length * ( float )Math.Sin(angle) + start_pos.Y; |
15 |
//这里的跟踪算法主要适用于匀速圆周运动类型的要跟踪,速率不变,一定的旋转角度 |
17 |
public static Vector2 Tracking(Vector2 start_pos, ref float direction, Vector2 dest_pos, |
18 |
float start_speed, float accel_speed, float track_degree, float use_time) |
20 |
Vector2 newpos = new Vector2(0, 0); |
28 |
direction = direction % 360; |
32 |
float degree =( float ) (Math.Atan2(dest_pos.Y - start_pos.Y, |
33 |
dest_pos.X - start_pos.X) * 180 / Math.PI); |
40 |
float dest_degree = ( float )Math.Abs(degree - direction) % 360; |
41 |
if (dest_degree > 180) |
43 |
dest_degree = 360 - dest_degree; |
45 |
if (dest_degree < 0.000001) |
47 |
GoStraight(start_pos, direction, start_speed, accel_speed, use_time, out newpos); |
52 |
float use_seconds = use_time / 1000.0f; |
53 |
float rotate_degree = track_degree * use_seconds; |
54 |
if (rotate_degree > dest_degree) |
56 |
rotate_degree = dest_degree; |
58 |
double inner_degree = degree - direction; |
59 |
if (inner_degree > 180) |
61 |
direction -= rotate_degree; |
63 |
else if (inner_degree <= 180 && inner_degree >= 0) |
65 |
direction += rotate_degree; |
67 |
else if (inner_degree < -180) |
69 |
direction += rotate_degree; |
71 |
else if (inner_degree >= -180 && inner_degree <= 0) |
73 |
direction -= rotate_degree; |
76 |
GoStraight(start_pos, direction, start_speed, accel_speed, use_time, out newpos); |
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程:简介及目录》(附上完整工程文件)
介绍:讲述如何使用Genesis-3D来制作一个横版格斗游戏,涉及如何制作连招系统,如何使用包围盒实现碰撞检测,软键盘的制作,场景切换,技能读表,简单怪物AI等等,并为您提供这个框架的全套资源,源码以 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程04:技能的输入与检测》
4.技能的输入与检测 概述: 技能系统的用户体验,制约着玩家对整个游戏的体验.游戏角色的技能华丽度,连招的顺利过渡,以及逼真的打击感,都作为一款游戏的卖点吸引着玩家的注意.开发者在开发游戏初期,会根据 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程01: 资源导入》
1. 资源导入 概述: 制作一款游戏需要用到很多资源,比如:模型.纹理.声音和脚本等.通常都是用其它相关制作资源软件,完成前期资源的收集工作.比如通常用的三维美术资源,会在Max.MAYA等相应软件中 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程08:虚拟键盘实现》--本系列完结
8.虚拟键盘实现 概述: 硬键盘就是物理键盘,平时敲的那种.软键盘是虚拟的键盘,不是在键盘上,而是在"屏幕"上.虚拟按键就是虚拟键盘的一部分,根据功能需求,提供部分按键效果的UI可 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程07:UI》
概述: UI即User Interface(用户界面)的简称.UI设计是指对软件的燃机交互.操作逻辑.界面美观的整体设计.好的UI设计不仅可以让游戏变得更有品位,更吸引玩家,还能充分体现开发者对游戏整 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程06:技能播放的逻辑关系》
6.技能播放的逻辑关系 技能播放概述: 当完成对技能输入与检测之后,程序就该对输入在缓存器中的按键操作与程序读取的技能表信息进行匹配,根据匹配结果播放相应的连招技能. 技能播放原理: 按键缓存器中内容 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程05:技能读表》
5.技能读表 技能读表概述: 技能读表,作为实现技能系统更为快捷的一种方式,被广泛应用到游戏开发中.技能配表,作为桥梁连接着游戏策划者和开发者在技能实现上的关系.在游戏技能开发中,开发者只需要根据策划 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程03:碰撞检测》
3.碰撞检测 碰撞检测的概述: 碰撞在物理学中表现为两粒子或物体间极端的相互作用.而在游戏世界中,游戏对象在游戏世界自身并不受物理左右,为了模拟真实世界的效果,需要开发者为其添加属性,以模拟真实事件的 ...
- 《Genesis-3D开源游戏引擎--横版格斗游戏制作教程02:关键帧动画导入与切割》
2. 关键帧动画导入与切割 动画的分割与导入概述: 在游戏当中,游戏角色在不同状态下会有不同的动作,这些动作在引擎里相当于一段段的动画片段.当导入模型资源的时候,连同模型动画都会一并导入到引擎中.开发 ...
- Beat 'Em Up Game Starter Kit (横版格斗游戏) cocos2d-x游戏源代码
浓缩精华.专注战斗! 游戏的本质是什么?界面?养成?NoNo! 游戏来源于对实战和比赛的模拟,所以它的本源就是对抗.就是战斗! 是挥洒热血的一种方式! 一个游戏最复杂最难做的是什么?UI?商城? ...
随机推荐
- ADO.NET基础02(语句参数化,配置文件,DataSet与DataTable)
ADO.NET连接池 ado.net默认启用了连接池 *如何清空连接池?Connection的静态方法ClearAllPools(). ClearPool() Ado.net连接池使用总结: 1.第一 ...
- IntelliJ IDEA 15开发Java Maven项目
1.安装好之后开始创建项目
- iOS:自定义工具栏、导航栏、标签栏
工具栏为UIToolBar,导航栏UINavigationBar,标签栏UITabBar.它们的样式基本上时差不多的,唯一的一点区别就是,工具栏一般需要自己去创建,然后添加到视图中,而导航栏和标签栏不 ...
- Objective-C命名编写规范
There are only two hard things in Computer Science: cache invalidation and naming things. 在计算机科学中只有两 ...
- Android列表视图(List View)
Android列表视图(ListView) ListView是一个显示滚动项列表的示视图组(viewgroup),通过使用适配器(Adapter)把这些列表项自动插入到列表中.适配器比如从一个数组或是 ...
- C#开发BHO插件UrlTrack
最近忽然突发奇想,想统计一下我最经常上的网站是哪些,并且在这些网站上都停留了多久.为此决定写一个BHO插件来做这件事. BHO(Browser Help Objects)是实现了特定接口(IObjec ...
- makefile的常用规则
一.前言 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容: 源程序编译 Makefile的编写 程序库的链接 程序的调试 头文件和系统求助 二.正文 1 ...
- android开发中如何结束所有的activity
每一个activity都有自己的生命周期,被打开了最终就要被关闭. 四种结束当前的activity方法 //关闭当前activity方法一 finish(); //关闭当前界面方法二 android. ...
- Android之界面刷新(invalidate和postInvalidate使用)
Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用. Android提供了Inva ...
- JS闭包的两个使用方向
直接上代码,备用,详见注释 <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="serve ...