| แฟ้มประวัติSunwing's note bookรูปถ่ายบล็อกรายการ | วิธีใช้ |
|
|
23 ธันวาคม 碰撞检测——矩形重叠碰撞测试,线段相交碰撞测试,线段交点 // rectangle hit test
public static boolean rectHitTest(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { if (Math.max(x1, x2) < Math.min(x3, x4) || Math.max(y1, y2) < Math.min(y3, y4) || Math.min(x1, x2) > Math.max(x3, x4) || Math.min(y1, y2) > Math.max(y3, y4)) { return false; } return true; } // segment hit test
public static boolean segmentHitTest(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { // fast hit test if (!rectHitTest(x1, y1, x2, y2, x3, y3, x4, y4)) { return false; } // segment hit test judgement /**/ if (vectorProduct(x1 - x3, y1 - y3, x4 - x3, y4 - y3) * vectorProduct(x2 - x3, y2 - y3, x4 - x3, y4 - y3) <= 0 && vectorProduct(x3 - x1, y3 - y1, x2 - x1, y2 - y1) * vectorProduct(x4 - x1, y4 - y1, x2 - x1, y2 - y1) <= 0) { return true; } /**/ return false; }
/**
* * @param x1 * @param y1 * @param x2 * @param y2 * @param x3 * @param y3 * @param x4 * @param y4 * @return int array * if return null, then the two segments are not crossed * if return array.length = 2, then segments are crossed at x=array[0], y=array[1] * if return array.length = 4, then segments are overlaped from * coordinate (array[0],array[1]) to (array[2], array[3]) * if return else then means error */ public static int[] segmentHitPoint(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) { if (!segmentHitTest(x1, y1, x2, y2, x3, y3, x4, y4)) return null; int k1, a1, k2, a2, x, y; int mathShift = 10; // on the same vertical line if (x1 == x2 && x3 == x4 && x1 == x2) { int maxY = Math.max(Math.max(y1, y2), Math.max(y3, y4)); int minY = Math.min(Math.min(y1, y2), Math.min(y3, y4)); int[] arrayY = new int[] { y1, y2, y3, y4 }; int[] result = new int[] { x1, 0, x1, 0 }; int index = 1, i = 0; while (i < 4 && index < 4) { if (arrayY[i] != maxY && arrayY[i] != minY) { result[index] = arrayY[i]; index += 2; } i++; } return result; } else if (x1 == x2) { k2 = (y3 - y4 << mathShift) / (x3 - x4); a2 = y3 - (k2 * x3 >> mathShift); x = x1; y = (x * k2 >> mathShift) + a2; } else if (x3 == x4) { k1 = (y1 - y2 << mathShift) / (x1 - x2); a1 = y1 - (k1 * x1 >> mathShift); x = x3; y = (x * k1 >> mathShift) + a1; } // normal state else { k1 = (y1 - y2 << mathShift) / (x1 - x2); k2 = (y3 - y4 << mathShift) / (x3 - x4); if (k1 == k2) { int maxX = Math.max(Math.max(x1, x2), Math.max(x3, x4)); int minX = Math.min(Math.min(x1, x2), Math.min(x3, x4)); int[] arrayX = new int[] { x1, x2, x3, x4 }; int[] arrayY = new int[] { y1, y2, y3, y4 }; int[] result = new int[4]; int index = 0, i = 0; while (i < 4 && index < 4) { if (arrayX[i] != maxX && arrayX[i] != minX) { result[index++] = arrayX[i]; result[index++] = arrayY[i]; } i++; } return result; }
a1 = y1 - (k1 * x1 >> mathShift); a2 = y3 - (k2 * x3 >> mathShift); x = (a2 - a1 << mathShift) / (k1 - k2); y = (x * k1 >> mathShift) + a1; } return new int[] { x, y }; } // get the vector product private static int vectorProduct(int x1, int y1, int x2, int y2) { return x1 * y2 - x2 * y1; } 19 ธันวาคม 策划学习笔记——sid meier 语录先考虑类型,然后再考虑游戏主题是十分危险的。
首先要确定游戏主题,然后找到合理的方式和适当的风格来制作。
Civilization 有一种神奇的吸引力,这并不出自策划本身。任何自然结合的事物都具备这种特质。Civilization 的成功是由于各部分协调一致的结果。(你个样好唔自然~)
让玩家用自己的知识来玩游戏。可以在游戏中应用自己的知识时,玩家会变得有自信。
如果趣味性和历史发生冲突,我们要服从趣味性。(可悲的历史...)
游戏可以分成3类:分别是设计者可以获得所有乐趣的游戏,AI可以获得所有乐趣的游戏,玩家可以获得所有乐趣的游戏。(好似AI可以获得所有乐趣的游戏好多...)
我们的原则是,尽可能让玩家有更多的选择。
13 ธันวาคม 游戏策划学习笔记--玩家的需要一、玩游戏的理由
1、挑战
所有游戏都必须具备挑战。
2、交流
3、独处的需要(译文是“独处的经历”)
与AI交流比与人交流省力,玩家需要私人的休息空间。
4、炫耀
5、情感体验
6、幻想
我的想法:设计得好的游戏不一定要涵括以上所有理由,而要针对某个理由将游戏特色发挥到极至。
也就是说要清楚游戏面向什么市场,并有效地坚持下来。
但是任何游戏必须具备挑战,这是做游戏的基本条件。
二、满足玩家的期望
1、由动作所产生的结果需要可预知性。无论失败或成功都需要清晰的原因
2、在同一个游戏的进行过程中,不要突然往其中插入与原游戏完全不相符的机制和规则。
3、预测玩家在游戏世界中会做些什么,并保证玩家尝试这些动作的时候会发生合乎情理的事情。
4、游戏需要一个目标,并且要让玩家清晰地了解该目标。
我的想法:对于大型游戏,目标需要有一定的吸引力。对于休闲类游戏,则不是太重要。
5、快速给予奖励,使玩家高昂的情绪不至于很快地消退,甚至觉得沮丧。
我的想法:对于策略类的游戏,第一次小奖励要在30分钟内给予,动作游戏和休闲游戏需要在1分钟内给予。
何谓小奖励?连击,连串动作并成功越过难关,组合按键发出的技能,致命一击等等。小奖励通常都伴随着华丽的声光效果,以带给玩家视听冲击。例如画面上跳跃出的 XX HIT, 冲击性大字体显示的致命一击的伤害,华丽而流畅的组合技。甚至只是表现出一气呵成的动作,就已经能带给玩家极大的满足感。
6、连续地让玩家沉浸于幻想世界,任何bug或者主角与玩家设想不一致的行为,都会打断玩家的幻想。
7、挑战性。游戏在一开始应该简单,但在游戏中期应该让玩家尝试失败,并且应该让玩家意识到,越过难关后会有更吸引的奖励。当然,如果没有,玩家会觉得沮丧。
8、游戏应该存在多种合理方式暗算玩家,一成不变只会让游戏失去吸引力。
9、自动存档
10、游戏不能存在一些无法跨越的障碍。
11、片头动画虽然吸引,但还是游戏本身更吸引。
12、玩家不知道他们要的是什么,但是他们知道什么是他们要的 05 ธันวาคม particle system粒子运动系统概述
(以下某些言论其实已经颇为过时,事实上粒子系统所产生的效果不如预期,所以各位应该着眼于运动这一部分。可以先看看www.gameres.com上面的相关文章。注意,我所讨论的是j2me。感谢我高中的物理老师司徒美仙)
一、粒子运动系统目的 实现与游戏世界无联系的物体运动。
二、粒子运动系统接口 1. 构造粒子 传入粒子的初始化数据,粒子会按照初始化数据作运动直到消亡,过程中无法对其轨迹作出任何影响。 2. 粒子运动 每帧调用运动接口,使粒子每帧作出运动。 3. 粒子显示 调用粒子显示接口,在屏幕上画出粒子。
三、运动的实质(参考高中物理学,微积分,参数方程等相关知识) 1. 运动的叠加 运动系统的基础。要描述一个在2D平面乃至3D空间中的运动,是颇为复杂的事。为了让问题简化,我们必须首先将运动分解。如果是2D平面的运动,则分解成x和y两个坐标轴上的运动叠加。这两个运动是相互无影响的。(参阅初中物理学课本,运动、力的分解)
2. 环境状态和初始状态 a) 环境状态:引力,弹力,风,阻力等 这些都是影响运动的因素,都是力,因为粒子无质量,所以在系统中直接以加速度表示。通常有: 阻尼系数p,无方向,阻力加速度 = -速度×阻尼系数。 如果环境是各向异性的,可以分别设定xy方向上的阻尼系数。如果阻力只与速度方向有关,则 阻力加速度 = -(|速度|/速度)×系数 平衡点,弹性势能为0的点。 弹性系数k,无方向,弹力加速度 = -相对于平衡点的位移×弹性系数,这里是把质量的因素整合到系数中考虑了。 其他力,包括重力。先自行把各个恒力合成,换算出xy上的加速度。
b) 初始状态:初速,初始加速度,起始坐标,生命周期
3. 运动的逻辑运算 在实际使用中,我们只关心某个时刻粒子的位置。但是运动是具有连续性的,因此可以通过上一时刻的位置计算出下一时刻的位置。 a) 匀速直线运动 无环境状态,运动全过程无力作用 速度 v 初位移 s0 则 s1 = s0 + v
b) 自由落体运动, 平抛运动, 斜抛运动 和 竖直上抛运动 ————环境———— 重力加速度 g = ay ————初始———— 初速度 vx0 vy0 初位移 x0 y0 ————计算———— 则: x1 = x0 + vx0 y1 = y0 + vy0 // 为再下一时刻计算 vx1 = vx0 vy1 = vy0 + g (做做看,x y上的两个竖直上抛运动的叠加,即有ax,ay,很有型的)
c) 简谐振动,正弦波动 和 圆周运动 ————环境———— 平衡点 Px Py 弹性系数 kx ky 无其他环境影响 ————初始———— 初始加速度 ax0 ay0
初速度 vx0 vy0 初位移 x0 y0 ————计算———— 则: x1 = x0 + vx0 y1 = y0 + vy0 // 为再下一时刻计算
vx1 = vx0 + ax0 vy1 = vy0 + ay0 ax1 = - (x1 - Px) × kx =(Px - x1) × kx
ay1 = - (y1 - Py) × ky =(Py - y1) × ky
为何简谐振动和圆周运动都是同样的算法? 因为实际上圆周运动就是由xy轴上,两个相位相差90度的简谐振动所合成。只要设置不同的初始状态,就可以得到不同的运动。 另外,只要在平衡点产生一个运动,就可以得到更复杂的运动了。 (叠加 n 个简谐振动会怎样呢? 呵呵,没试过)
d) 其他运动 计算流程都是一样的。 先通过已知的上一时刻速度计算下一时刻的 x y 坐标 再通过上一时刻的加速度计算下一时刻的 速度 然后是计算下一时刻的 加速度
所有的计算基本上都是+-法,因此速度是十分快的。这也是采取这种运动计算方法的优势所在。
控制对象这里,控制对象的“控制”是形容词而非动词。
1、控制对象的由来
在程序模块化的过程中,最常见的一个情况是:进入某个系统并退出后,程序的逻辑改变。而我们要讨论的问题是:如何低耦合地实现?我的结论是——控制对象。
2、控制对象的使用
以《战国》的窗口系统为例。
窗口系统的出现,是由于源程序中严重的重用性不足,导致代码量过长以及难以想象的复杂度。窗口系统简化了关于窗口部分的画图代码,简化了窗口控制流程,但是对于逻辑上的耦合一直是个非常大的问题。一些新窗口的创建,选项导致的主程序逻辑跳转等等,通通都在该系统中实现。因此它严格上来说还不能算是一个系统模块,高耦合使名义上的窗口不能剥离为其他程序所用。
如何使其独立出来?
其实耦合的程序都可以看成是一段段子程序,在系统外执行,只是由于全局变量的方便使用而写到系统中。
首先,主程序需要标记去判断应该执行什么子程序。这些标记就是控制对象。
其次,系统中不应该对控制对象进行任何处理。控制对象应该原封不动地送还主程序。
在窗口系统中,所有的控制跳转都是由于确定键按下所触发的。所以窗口系统送还控制对象的通道就是按键接口。如果送还null则表示无对应的控制对象。
最后,在构建窗口时传入控制对象列表与每个窗口选项相对应。
in a word,使用控制对象的方法就是不使用。控制对象是用于主程序对全局的判断,而不是独立系统应该去处理的。
|
|
|