SOURCE:NOIP2015-SHY-9
Stack Ball 堆栈球小游戏unity3d开发教程
Posted 小云同志你好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Stack Ball 堆栈球小游戏unity3d开发教程相关的知识,希望对你有一定的参考价值。
Stack Ball 堆栈球小游戏unity3d开发教程
介绍
《Stack Ball》是一款3D街机游戏,玩家需要通过旋转的螺旋平台来打碎、撞击和弹跳,以达到终点。
听起来很容易?你可错了!!
你的球会像砖头一样撞破阻挡下降的彩色平台,但如果碰到黑色平台,游戏就结束了!你的球会破碎成碎片,你必须重新开始下落。
但即使黑色平台也无法阻挡以全速下落的火球!像疯子一样加速或者停下来等待下一次滚动和跳跃的机会。其他球类游戏都希望自己能像这样有趣!
为什么《Stack Ball》很棒:
-疯狂的快速速度
-有趣的玩法
-简单生动的图形
-简单易上手
-极好的浪费时间
旋转堆栈(Rotator.cs)
Rotator是所有堆栈的父级,请查看下面的Rotator.cs代码和注释以了解其功能:
请注意,由于所有的堆栈都是Rotator的子级,因此当Rotator旋转时,所有的堆栈都会跟着旋转
// Rotator.cs
// Rotator.cs 被添加到空的gameobject 上,位置是0,0,0,而不是绿色圆柱体上。
public class Rotator : MonoBehaviour
public float speed = 100;
void Update()
transform.Rotate(new Vector3(0, speed * Time.deltaTime, 0));
// 所有的堆栈都是Rotator的子对象,因此旋转Rotator会导致所有堆栈跟着旋转。
stacks rotate
调整中心圆柱体的位置和旋转,使其在游戏场景中看起来更好
那么如何实现每个堆栈从上到下都偏移一定的旋转角度?
for loop:
tempStack = Instantiate(prefab)
tempStack .transform.position = new Vector3(0, i-0.01f, 0); // 每个堆栈相对于上一个堆栈偏移0.01f。
tempStack .transform.eulerAngles = new Vector3(0, i*8,0)
当所有堆栈添加完毕后,结束部分预制体将被实例化并添加到场景中。
我们将以最后一个堆栈的Y位置为基础来设置最终结束gameobject的Y位置。
堆栈破坏
堆栈的黑色部分:
游戏中一层堆栈有一部分是黑色的,当球向下撞击并触碰到它时,游戏会失败。
这里设置tag为"plane"
这里设置tag为"enemy"
if (target.gameObject.tag == "enemy")
target.transform.parent.GetComponent<StackController>().ShatterAllParts();
if (target.gameObject.tag == "plane")
rb.isKinematic = true;
transform.GetChild(0).gameObject.SetActive(false);
playerState = PlayerState.Died; // 游戏失败
SoundManager.instance.PlaySoundFX(deadClip, 0.5f);
请注意,当球与黑色部分碰撞时,球的刚体(rigidbody)的isKinematic被设置为true。如果启用了isKinematic,则力,碰撞或连接将不再影响刚体(rigidbody)。通过改变transform.position,刚体将完全由动画或脚本控制。 基本上,球将不再反弹。
每个部分都附带有脚本(StackPartController.cs)此脚本将控制每个部分在破碎时会发生什么:
1)rigidBody.isKinematic = false;//在破碎后会受到重力的影响。
2)collider.enabled = false;//禁用碰撞器(collider)。
3) rigidBody.AddForceAtPosition(dir * force, forcePoint, ForceMode.Impulse);
4) rigidBody.AddTorque(Vector3.left * torque);
关于 1)
最初,每个部分的刚体的isKinematic被设置为true,useGravity被设置为true。
因此,每个部分在球破碎之前都不会掉落。破碎时,只需将每个部分的isKinematic设置为false。
关于 2)
dir的计算方式为:
Vector3 dir = (Vector3.up * 1.5f + subDir).normalized;
首先,向上是基本方向,破碎的部分将向上飞行。
然后,subDir是左或右,基于破碎的部分相对于堆栈中心的位置。
游戏控制
用户输入处理:
检测是否按下屏幕,如果是,则表示球应该向下撞击。
if (Input.GetMouseButtonDown(0))
smash = true;
if (Input.GetMouseButtonUp(0))
smash = false;
// 关于检测输入,请不要将代码放在FixedUpdate中,否则可能会错过用户输入事件。
接下来,我们将实现球向下撞击的逻辑。
在FixedUpdate()中,当smash为true时,我们将刚体的速度设置为负y轴,以使其以一定速度向下移动。
无敌模式充能
currentTime表示充能到无敌模式的进度。
currentTime将是在0和1之间增加和减少的变量。
if (smash) // 如果正在撞击,则奖励玩家增加currentTime,该变量表示充电到无敌模式的进度
currentTime += Time.deltaTime * .8f;
else //如果没有撞击,则进度会下降,但0.5f比0.8f慢
currentTime -= Time.deltaTime * .5f;
无敌模式倒计时
if (invincible)
currentTime -= Time.deltaTime * .35f; // 每秒计数减少35%
if (!fireEffect.activeInHierarchy)
fireEffect.SetActive(true);
if (currentTime <= 0)
currentTime = 0;
invincible = false; // 当currentTime减少到0时,无敌模式结束
invincibleFill.color = Color.white;
无敌进度UI
图像类型为Filled,可以使进度条效果更好
润色
即使处于空闲跳跃状态,视觉效果也是超级休闲游戏的关键。
如何使球撞击堆栈时产生溅落特效(Splash Effect)。
GameObject splash = Instantiate(splashEffect);
splash.transform.SetParent(target.transform); // 特效的位置留在堆栈上
splash.transform.position = new Vector3(transform.position.x, transform.position.y - 0.22f, transform.position.z);//我们将球撞击的堆栈设置为splash的父级,然后稍后,splash将停留在原地并与堆栈一起旋转
#####这里transform.position是球的全局位置。
整理好后奉上游戏源码谢谢大家支持
刷题总结——ball(ssoj)
题目:
题目背景
题目描述
Alice 与 Bob 在玩游戏。他们一共玩了 t 轮游戏。游戏中,他们分别获得了 n 个和 m 个小球。每个球上有一个分数。每个人的得分都为他所获得所有小球分数的乘积,分数小者获胜。问每轮游戏谁会获胜?请输出每轮游戏的胜者。数据保证不会出现平局,且两个人分数差异大于任意一个人分数的 1% 。
输入格式
第一行为两人玩的轮数 t(1≤t≤10)。
每一轮游戏的输入中:
第一行一个整数 n,代表 Alice 获得球的个数。
第二行为 n 个整数 ai,代表 Alice 每个球的分数。
第三行一个整数 m,代表 Bob 获得球的个数。
第四行为 m 个整数 bi,代表 Bob 每个球的分数。
输出格式
输出共 t 行,每行为该轮胜者的名字“Alice”或“Bob”。
样例数据 1
备注
【样例说明】
Alice:2 * 3 * 4 = 24
Bob: 1 * 3 * 4 * 5 = 60
【数据范围】
对于 40% 的数据:n,m,ai,bi≤10;
对于 100% 的数据:1≤n,m≤100000;-10000≤ai,bi≤10000。
题解:
由于乘积过大容易想到把乘积转换为加减形式····所以联想到了对每一个乘数取log然后相加比较··
注意判断负数和0的情况
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; inline int R() { char c;int f=0,i=1; for(c=getchar();(c<‘0‘||c>‘9‘)&&c!=‘-‘;c=getchar()); if(c==‘-‘) c=getchar(),i=-1; for(;c<=‘9‘&&c>=‘0‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f*i; } int T,n,m,cnt1,cnt2; double tot1,tot2; inline double Abs(int a) { double t=a; return t<0?-t:t; } int main() { //freopen("a.in","r",stdin); T=R();double a; while(T--) { bool flag1=false,flag2=false; tot1=tot2=0; n=R();cnt1=0; for(int i=1;i<=n;i++) { a=R();if(a<0) cnt1++; else if(a==0) flag1=true; tot1+=log(Abs(a)); } m=R();cnt2=0; for(int i=1;i<=m;i++) { a=R();if(a<0) cnt2++; else if(a==0) flag2=true; tot2+=log(Abs(a)); } if(flag1==true&&cnt2%2==0) cout<<"Alice"<<endl; else if(flag1==true&&cnt2%2==1) cout<<"Bob"<<endl; else if(flag2==true&&cnt1%2==0) cout<<"Bob"<<endl; else if(flag2==true&&cnt1%2==1) cout<<"Alice"<<endl; else if(cnt1%2==1&&cnt2%2==0) cout<<"Alice"<<endl; else if(cnt1%2==0&&cnt2%2==1) cout<<"Bob"<<endl; else if(cnt1%2==0&&cnt2%2==0) { if(tot1<tot2) cout<<"Alice"<<endl; else cout<<"Bob"<<endl; } else if(cnt1%2==1&&cnt2%2==1) { if(tot1<tot2) cout<<"Bob"<<endl; else cout<<"Alice"<<endl; } } return 0; }
以上是关于Stack Ball 堆栈球小游戏unity3d开发教程的主要内容,如果未能解决你的问题,请参考以下文章