在游戏里,我是怎样做出分身效果?

<来自cnmm22:http://blog.csdn.net/cnmm22/article/details/44747783>

我是怎样完成了里世界,分身。

我之前已经完成了夜撩,大阳气炮,夜撩断魂,中华宝轮……后来证明,要实现是世界,分身是一件相当困难的事情,这几乎花了我两天的时间。

我前后想过很多办法,实现的结果不是很理想:

最开始,我想得很简单,就是记录一个时间差,比如只需要记住主角3秒钟前的坐标和攻击方位就行。

后来证明,这种想法太过幼稚。

不过是在实践中才得出这个结论,我这样做了,首先,我建了一个分身类,继承了我自己,省略了若干的方法,只留一个主干,其中包括绘制方法。接下来,我用几个常量记录3秒钟前的坐标和攻击方位,后来的结果是,分身几乎无法移动,即使移动也是瞬间移动。

所以,我想到了,用一个数组,因为我意识到,要顺滑的表现出分身的移动,分身其实就是重复我的移动,那实际上需要记录的是一系列数据,比如他是重复我3秒前的移动,那我不应该只记录3秒前我的状态,而必须记录我在3秒钟里几乎所有状态!

OK,现在开始做,我做了如下改进:我用一个二维数组,比如a[][],第一个下标代表3秒内的每一帧,第二个下标取值为0-2,记录3个数据,x坐标,
y坐标,攻击方向。那从现在(假设已经是3秒后往前推,a[0][0]就带表3秒前第一帧的x坐标,a[100][2]代表大概1秒前的攻击方向。

我把这些数据传递给我的分身,我在分身里定义了相应的3个静态常量,之所以要静态的,是为了方便赋值,因为这些常量我只需要一份,因为同一个分身不可能有多个实例。这时,我想到的是我做一个分身就行了,所以,比如x,y坐标和攻击方向,我只需要一份(当然你也看到了,实际上我做出了多个分身的效果)。

但是,现在问题来了,主要问题有两个:

1、  攻击方向我是定义的一个枚举常量,数组中无法同时传递int 和枚举数据;

2、  最关键的,数组的大小是固定的,我该要定义多大的数组?我也许试过a[10000][3],很显然,我需要分身战斗200秒,每秒假设绘制50帧,那数组可能越界,而且这样会很耗内存,因为内存得不到释放。

所以我必须改变,要同时解决上面两个问题,我思考后,改进为:

我先定义了一个内部类(他们就是最后我完成的方式了,现在我可以粘贴一些代码了):

class Date {

int dx;

int dy;

Directionddir;

public Date(int dx, int dy,
Direction ddir) {

this.dx = dx;

this.dy = dy;

this.ddir = ddir;

}

}

短短几行,却包含了足够信息。

完后,该是一个集合来盛放这些Date对象了,当然LIST和内部类简直是完美的搭配。代码如下:

List<Date> s;

我曾今考虑过这里用一个链表来装这个集合,因为这里不涉及到很多的随机读取,不过考虑到实际实现他后,list 的长度也只有不到20(通常情况下永远不会超过30,后面我会讲实现),所以我只是用了一个ArrayList轻松搞定。

在按下分身键后,一系列的计算开始了:(这就是说不按分身时是不需要去计算和保存list滴)

if (dir !=
Direction.stop) {    //如果我在移动,才放入我的状态Date

if (fs1 >
0) {       //fs1代表我随机出几个分身,最多4个,我不想要再多了

// if(ap)

a++;       //a和b决定了分身跟我的位置。

Dated = new Date(x, y, dir);  
//每一次,只要我在移动,记录我的状态到一个Date里,很重要的,必须要移动才记录,否则结果会很尴尬,这是我试出来的,同时这个也保证list 的 size不会太大。

if (s == null)   
//因为按下分身后,是一个TimerTask 在记录分身时间,到时则要清理相关的a,b,s等所有信息,释放内存资源,并避免下一次激活分身冲突。

s = newArrayList<Date>();

if (Unit.Dfs)
{ //工具类,如果为真打印调试信息,毕竟项目有些大了。

System.out.println(b + "   
a=   "+ a + " 
" + ",g24.size=   "+ t.g24.size()
+ "   " + ",s.size=   "+ s.size());

}

s.add(d);

if (fs1 ==
1) {   //如果有一个分身,至少有一个。

if (a > b)
{//a和b决定了分身跟我的位置。b是每一次timer.cancel时计算的随机值,以供下次激活分身使用。a是每帧自增长而b 是固定不变,比如当b 为17,这个算式代表了,a 将会在17帧后执行下面得操作。

// ap=false;

Funk24.x = s.get(0).dx; 
//Funk24为分身类

Funk24.y = s.get(0).dy;

Funk24.dir = s.get(0).ddir;

s.remove(0);      //非常关键的,由s.remove(0)和s.get(0).dx;组合成了一个记录,实现机器,并且保证了整个list的大小不会超过b 的大小。

}

}

if (fs1 ==
2) {//如果有2个分身,第一个的出现是必然的,但第二个可能有3种情况,这里是因为我设计了4个不同的分身,而且为他们每一个都设计了单独的类,这是我塑造分身性格的一部分,在我的游戏里,分身是具备不同性格的,也有一些随机性。

if (a > b +
Unit.UF1) {  // Unit.UF1这里等于5,实际上代表了2个分身之间的距离,当然也可以是随机数,我这里用到工具类,可以方便的进行修改。

Funk24.x = s.get(Unit.UF1).dx;

Funk24.y = s.get(Unit.UF1).dy;

Funk24.dir = s.get(Unit.UF1).ddir;

s.remove(0);      //非常重要的,一定要在list最大的哪种if情形下remove(0),其他情形不用 remove。

}

if (a > b)
{// Funk241- Funk243 和Funk24是所有的4个分身类

if (Funk241.g241 ==
1) {// Funk241.g241 == 1就是说Funk241 被实例化了

Funk241.x = s.get(0).dx;

Funk241.y = s.get(0).dy;

Funk241.dir = s.get(0).ddir;

}

if (Funk242.g242 ==
1) {

Funk242.x = s.get(0).dx;

Funk242.y = s.get(0).dy;

Funk242.dir = s.get(0).ddir;

}

if (Funk243.g243 ==
1) {

Funk243.x = s.get(0).dx;

Funk243.y = s.get(0).dy;

Funk243.dir = s.get(0).ddir;

}

}

}

if (fs1 ==
3) {//如果有3个分身,组合的可能最多,最复杂,但实际也不复杂,有规律

if (a > b +
Unit.UF2) {// Unit.UF2同理是第三个跟第一个的距离

Funk24.x = s.get(Unit.UF2).dx;

Funk24.y = s.get(Unit.UF2).dy;

Funk24.dir = s.get(Unit.UF2).ddir;

s.remove(0); // b +
Unit.UF2无疑是list最大情形,所以在这里s.remove(0).

}

if (Funk241.g241 ==
1 && Funk242.g242 == 1) {// Funk241.g241 ==
1就是说Funk241 被实例化了

if (a > b +
Unit.UF1) {

Funk241.x = s.get(Unit.UF1).dx;

Funk241.y = s.get(Unit.UF1).dy;

Funk241.dir = s.get(Unit.UF1).ddir;

}

if (a > b)
{

Funk242.x = s.get(0).dx;

Funk242.y = s.get(0).dy;

Funk242.dir = s.get(0).ddir;

}

}

if (Funk241.g241 ==
1 && Funk243.g243 == 1) {

if (a > b +
Unit.UF1) {

Funk241.x = s.get(Unit.UF1).dx;

Funk241.y = s.get(Unit.UF1).dy;

Funk241.dir = s.get(Unit.UF1).ddir;

}

if (a > b)
{

Funk243.x = s.get(0).dx;

Funk243.y = s.get(0).dy;

Funk243.dir = s.get(0).ddir;

}

}

if (Funk243.g243 ==
1 && Funk242.g242 == 1) {

if (a > b +
Unit.UF1) {

Funk242.x = s.get(Unit.UF1).dx;

Funk242.y = s.get(Unit.UF1).dy;

Funk242.dir = s.get(Unit.UF1).ddir;

}

if (a > b)
{

Funk243.x = s.get(0).dx;

Funk243.y = s.get(0).dy;

Funk243.dir = s.get(0).ddir;

}

}

}

if (fs1 ==
4) {//如有4个分身,Unit.UF3是第4个跟第一个的距离,这种情形很简单,同时也可以很清楚的看出整个计算流程。

if (a > b +
Unit.UF3) {

Funk24.x = s.get(Unit.UF3).dx;

Funk24.y = s.get(Unit.UF3).dy;

Funk24.dir = s.get(Unit.UF3).ddir;

s.remove(0);

}

if (a > b +
Unit.UF2) {

Funk241.x = s.get(Unit.UF2).dx;

Funk241.y = s.get(Unit.UF2).dy;

Funk241.dir = s.get(Unit.UF2).ddir;

}

if (a > b +
Unit.UF1) {

Funk242.x = s.get(Unit.UF1).dx;

Funk242.y = s.get(Unit.UF1).dy;

Funk242.dir = s.get(Unit.UF1).ddir;

}

if (a > b)
{

Funk243.x = s.get(0).dx;

Funk243.y = s.get(0).dy;

Funk243.dir = s.get(0).ddir;

}

}

if (Unit.Ds11)
{

System.out.println(s.size());//s从未超过过30.

}

}

}

以上就是实现分身的主要代码,除开建立类之外也只有他们了,他们并没有增加很多运算复杂程度。最后press分身键时。

case KeyEvent.VK_Q:

if (fss >
0) { // 能放几炮

if (!fs)
{ // 是否已经放出

fs1++; // 一个分身加一

Funk24g = new Funk24(x, y, dir, t,
Unit.color3);

t.g24.add(g); 
   //分身有专门的队列g24.

fss -= 1;

fs = true;

if (r.nextInt(2)
== 1) { //除了第一个分身,234个分身出现都是有一定几率的。

fs1++;

Funk241g1 = new Funk241(x, y, dir, t,
Unit.color4);

t.g24.add(g1);

}

if (r.nextInt(2)
== 1) {

fs1++;

Funk242g2 = new Funk242(x, y, dir, t,
Unit.color5);

t.g24.add(g2);

}

if (r.nextInt(2)
== 1) {

fs1++;

Funk243g3 = new Funk243(x, y, dir, t,
Unit.color6);

t.g24.add(g3);

}

// timer = new Timer(); 千万不要每次都new
Timer !

timer.schedule(new TimerTask()
{

public void run()
{

if (!FunkD.pas)
{

if (FunkD.restart)
{

t.g24.clear();

s = null;

a = 0;

fs1 = 0;

b = r.nextInt(17);

cancel();

System.out.println("1========================");

}

fse++; // 计时

if (fse ==
10) {

fs = false;

fse = 0;

if (t.g24.size()
> 0) {

t.g24.clear();

}

s = null;

a = 0;

fs1 = 0;

b = r.nextInt(17);

cancel();

System.out.println("1========================");

}

}

}

},0, 1000); // 40秒等待

}

}

break;

最后,我正在尝试不使用任何开发包,不使用任何工具,用最原始的java代码来开发一个游戏。那是一个很火爆的游戏:

时间: 2024-10-10 20:51:55

在游戏里,我是怎样做出分身效果?的相关文章

如何做出游戏里一个字一个字打出的效果

大概是这样的效果: 第一步,找一个输出的地方. --/index.html --. <div id="out" style="--"><div> --. 第二步,JS代码部分. //找对象 out=document.querySelector("#output"); //创建一个输出的方法 function output(say){ out.innerHTML="";     //清空对话框里的内容 s

游戏里的三角形

你可能还没意识,其实游戏里是充满三角的.举个例子,想象你有一个飞船游戏,然会你要计算那些飞船之间的距离. 你有每艘飞船的X,Y坐标位置,但你怎么找到它们的距离呢? 很简单,你可以像这样从一艘飞船的中心画一条线到另一艘飞船,就像这样: 用勾股定理(原文对勾股定理的解释好长,我觉得没必要吧...) 总结来说,三角学就是你能够用来计算三角形的角度和边的长度的数学.人们常常会用到. 举个例子来说,在飞船游戏里你可能会要实现: 一艘飞船向另一艘飞船的方向发射激光 让一艘飞船向着另一艘飞船的方向移动 敌方飞

游戏里的编程游戏

我想写一本书,当然本身带有功利性,不必讳言,它并不是一本正儿八经的技术著作,它主要关于我人生里的游戏,游戏里的编程.最终未必能出书也并不特别重要,出不了无非是笔者水平不足或没有遇到自己的伯乐.同样重要的是,如果我能通过这个平台去分享我的游戏经历,我的人生,能得到诸位关注和共鸣,也是人生的一件快事!曾经我想写本自传,考虑到自己平淡无奇并且有些落魄的人生估计除了自己,谁有兴趣去回顾一下呢?每次同学会,我都以哥今时今日的身份和地位是不会去参加等理由推脱了.自古成王败寇,这是我们这个霸权乐土上至今未必的

C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判定玩家是否有权限做出这种选择,然后才决定是否为玩家执行此选择.例如,<仙剑奇侠传>这款游戏,进入剧情"荷叶迷宫时",会要求玩家击碎迷宫里的5尊雕塑,如图5-12所示.但是击碎的前提是,玩家身上必须携带有"锤子".也就是说系统会遍历玩家身上所有的资源,如果有锤

MVC4下如何实现模态弹出对话框效果--对话框里可以实现翻页效果(2)

其实上文只是对如何加代码的顺序方法的表述,这里面的代码每个函数是什么意思,要如何理解?需要我们深思. 我们先大框子去理解:我们上文在控制器里只是去HTTPGET了,HTTPget理解其实就是请求.那么我么要保存,要插入的时候要怎么做. 上文在控制器里增加了NEW的动作,当然我们要增加NEW的视图(New.cshtml),视图里面会有一个代码. using(Ajax.BeginForm("New","DataModule",new AjaxOptions{ Inser

亿级粉丝的初音未来、洛天依,咋在游戏里,总扮路人甲?

洛天依一下子在近来变成了一个很火的存在.没别的,她上了央视,并且在大热的文化综艺节目<经典咏流传>上献唱了一曲. 或许很多人并不熟悉歌手洛天依. 毕竟,对于二次元(主要为游戏.动画.漫画.小说)以外的人来说,她就是一个无名的存在. 洛天依是谁? 简单来说就是通过音乐生成软件,配合上专门的音源库,在通过手绘的2D形象或者3D形象来演绎歌唱的虚拟偶像. 至于打破次元壁,则是通过3D全息投影之类的技术来实现. 一般来说,公认的全球虚拟偶像应该是2007年诞生于日本的初音未来. 或许有人会联想到前些年

零元学Expression Design 4 - Chapter 5 教你如何用自制笔刷在5分钟内做出设计感效果

原文:零元学Expression Design 4 - Chapter 5 教你如何用自制笔刷在5分钟内做出设计感效果 本章将教你如何运用笔刷与简单线条,只要5分钟,就能做出设计感效果 ? 本章将教你如何运用笔刷与简单线条,只要5分钟,就能做出设计感效果 ? ? 本章范例的最终图: ? ? 开始吧~! ? 01 首先,在画面上拉出四个宽.高皆为10px的正方形 ? 如下图,四个方块由上至下颜色分别是#000000.#A1A1A1.#4D4D4D.#D6D6D6 ? 接着使用上一章学到的自制笔刷方

如果你在一款游戏里被困七天,获得的所有东西都能带回现实,但是死亡也会真的死亡,你会选择哪款游戏?

首先七天按照我们的时间算 即玩一个游戏七天 会死,也会获得游戏里的东西 首先,RPG 然后,选三国群侠传 七天这个游戏,睡客栈很快恢复 那些物品都是古董,一大堆的古董 还有各种神奇物品 只要不是脸太黑,都不会死吧... 或者干脆一级就不走了,在出生点等回家,身上也有超多古董文物了 有仙术,古董,神物,爽,无敌了 原文地址:https://www.cnblogs.com/yangzihong/p/12585847.html

转帖: 代理模式在游戏里的应用

原帖地址及作者的github: http://alloyteam.github.com/StreetFighter/ 代理模式的定义是把对一个对象的访问, 交给另一个代理对象来操作. 举一个例子, 我在追一个MM想给她送一束花,但是我因为我性格比较腼腆,所以我托付了MM的一个好朋友来送. 这个例子不是非常好, 至少我们没看出代理模式有什么大的用处,因为追MM更好的方式是送一台宝马. 再举个例子,假如我每天都得写工作日报( 其实没有这么惨 ). 我的日报最后会让总监审阅. 如果我们都直接把日报发给