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, outVector2 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?商城? ...
随机推荐
- C# Java间进行RSA加密解密交互
原文:C# Java间进行RSA加密解密交互 这里,讲一下RSA算法加解密在C#和Java之间交互的问题,这两天纠结了很久,也看了很多其他人写的文章,颇受裨益,但没能解决我的实际问题,终于,还是被我捣 ...
- Unrecognized selector sent to instance xxxxxxx
两个界面传递参数时报这个错误,经检查发现,是因为目标视图没有关联对应的controller.
- 【HDOJ】1800 Flying to the Mars
1. 题目描述挺简单的一道题,给定$n$个大整数,求出现最多的次数. 2. 基本思路这题是可以使用哈希做,ELFHash等哈希都可以过. 3. 代码 /* 1800 */ #include <i ...
- MySQL select into 和 SQL select into
现在有张表为student,我想将这个表里面的数据复制到一个为dust的新表中去,虽然可以用以下语句进行复制,总觉得不爽,希望各位帮助下我,谢谢. answer 01: create table d ...
- uva10820Send a Table
筛法. 首先使cnt[i]=sqr(n/i),这样cnt[i]就表示gcd(x,y)大于等于i的数对的个数,然后倒序枚举减去gcd大于i的个数就可以得到ans[i].最终得到ans[1]. 这个算法单 ...
- MSSQL中把表中的数据导出成Insert
use master go if exists (select name from sysobjects where name = 'sp_generate_insert_script') begin ...
- BZOJ3105: [cqoi2013]新Nim游戏
题解: 线性基?类似于向量上的基底. 此题题解戳这里:http://blog.csdn.net/wyfcyx_forever/article/details/39477673 代码: #include ...
- SDOI 2010 and SXOI 2014 地精部落 (递推)
用E[i,j]表示共有i个数字,以1..j开头且一开始下降的方案数的总和.则我们有: E[i,j]:=E[I,J-1]+E[i-1,i-j] 我们先来证明上升与下降的方案是一一对应的. 事实上,若有a ...
- javascript中的关键字和保留字
javascript中关键字的问题,将名称替换了下,确实就没有问题了.现在将它的关键字和保留字贴出来,便于日后查看和避免在次出现类似的问题. 1 关键字breakcasecatchcontinuede ...
- MYSQL查询数据库表索引的硬盘空间占用
查询数据库的占用 SELECT CONCAT(ROUND(SUM(index_length)/(1024*1024), 2), ' MB') AS 'Total Index Size' , CONCA ...