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)

题目:

题目背景

SOURCE:NOIP2015-SHY-9

题目描述

Alice 与 Bob 在玩游戏。他们一共玩了 t 轮游戏。游戏中,他们分别获得了 n 个和 m 个小球。每个球上有一个分数。每个人的得分都为他所获得所有小球分数的乘积,分数小者获胜。问每轮游戏谁会获胜?请输出每轮游戏的胜者。数据保证不会出现平局,且两个人分数差异大于任意一个人分数的 1% 。

输入格式

第一行为两人玩的轮数 t(1≤t≤10)。
每一轮游戏的输入中:
第一行一个整数 n,代表 Alice 获得球的个数。
第二行为 n 个整数 ai,代表 Alice 每个球的分数。
第三行一个整数 m,代表 Bob 获得球的个数。
第四行为 m 个整数 bi,代表 Bob 每个球的分数。

输出格式

输出共 t 行,每行为该轮胜者的名字“Alice”或“Bob”。

样例数据 1

输入  [复制]

 

 



2 3 4 

1 3 4 5

输出

Alice

备注

【样例说明】
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开发教程的主要内容,如果未能解决你的问题,请参考以下文章

深入浅出游戏算法-unity3d算法-球转动

Unity3D数据集合堆栈Stack和队列Queue学习

Unity3D数据集合堆栈Stack和队列Queue学习

刷题总结——ball(ssoj)

如何使相机跟随unity3d C#中的对象?

计算球击中目标所需的初始速度