Cheer Up

游戏说明:

除了音效,游戏地图上的元素有:

草丛(玩家可以躲进去,敌人攻击不到) 
河流(双方都过不去,但是子弹可以穿过) 
铁墙(坦克和子弹都过不去) 
砖墙(一发子弹摧毁后坦克可以过去)
空气墙(围在地图周围,防止出界) 
敌方大坦克(打两下才死)
敌方小坦克(打一下就死)
有玩家1和玩家2,可以选择单人/双人模式

❥地图是随机生成的,每次打开都不一样,丰富了游戏的多样性和可玩性。敌方坦克(包括大小坦克)一次最多存在3个,被摧毁后间隔3s在地图的左上/右上/上面中间 随机生成相应数量的。

❥输赢的判断:

敌方坦克数目一定,每消灭一个获得1分,消灭满20个,也就就是得分20分获得胜利,玩家自己有3生命值(即3条生命),被击中一次损失1条生命并且在出生点复活,获得3s的无敌效果。生命耗尽或者老家被摧毁,就game over。

可以理解为有10个类:


☀️项目效果展示

  • 这里的gif是用了一款ScreenToGif的软件录制的,处理的比较短
  • 右侧图标分别表示消灭的敌人数量(上) 和 当前的生命值(下),被击中一次生命值-1,变为0的时候玩家死亡,游戏结束

目录

☀️项目效果展示

☀️前言

⭐️相关背景

⭐️相关知识

⭐️版本说明

⭐️许可证激活

⭐️及时保存

☀️项目概况

⭐️项目整体布局

⭐️猜想验证

⭐️分步介绍(结合代码)

❀Audio.cs

❀Born.cs

❀Bullet.cs

❀Enemy.cs

❀Explosion.cs

❀Heart.cs

❀MapCreation.cs

❀Option.cs

❀Player.cs

❀PlayerManager.cs


☀️前言

⭐️相关背景

  • 博主在大二暑期接触了unity,借鉴实战视频上手花两天复刻了 “坦克大战” 这一经典小游戏,发现做游戏这种过程真的比玩儿游戏还要爽啊,hh,看着一些功能逐渐被实现,游戏越来越完整,真的是挺令人舒适和爽快。由于那时候零基础直接上手,对于一些基础操作真的是不太熟练,很不灵活,幸好有一些前辈的帮助(比如CSDN小伙伴们熟悉的y哥),解决了一些自己难以解决的问题,帮助小虾在迷茫的夜海上拨开神秘的迷雾。

⭐️相关知识

  • 在学习的过程中,几个比较重要的知识点就是:预制体、克隆体、精灵渲染器、渲染层级、脚本、碰撞检测、触发检测、AI设计、UI设计、固定物理帧...

⭐️版本说明

  • 小虾采用的是Unity一个较新的版本-2021.1.16,这里建议小伙伴们下载和教程相同版本的,不然真的会有可能遇到卡点消耗心情哈。
  • 可以和我一样在Unity Hub里面安装,Hub感觉挺好用的。

⭐️许可证激活

  • 这个...有段时间不登好像就要重新激活许可证,遇到同样问题的小伙伴可以进入下图的网址:Unity - Activation 按提示进行操作即可

⭐️及时保存

  • 打开的时候总是激动又煎熬,U3D启动有点慢并且操作过程中很可能就会报废,所以项目过程中一定要及时保存,不然一不小心可能就要重新来过啦!


☀️项目概况

⭐️项目整体布局

  • 整个项目工程的一个概况就在下面了,Hierarchy菜单下是放 预制体(Prefab) 的 克隆体(Clone) 的,这些克隆体可以拖到左上方的大界面中,通过点击播放按钮进行效果检验。左下方的就是整体的动画效果显示了。
  • 做一个小游戏项目,我们首先需要素材,这里推荐初学的小伙伴去siki学院学习,里面会有相应的完整初级案例教程。

⭐️猜想验证

  • 学习的过程就是不断验证猜想并接收新知识的过程,我本来想坦克大战里面的地图就是把预先处理好的 “砖墙、水泥墙、草坪、河流、空气墙(防止Object越过边界的)” 按照一定规律和自己的喜好摆放开来作为整张地图的,但事实打脸了(觉得自己真傻)。
  •  地图实例化(MapCreation) 中,我们使用了 “产生随机位置” 的方法,在避开已有位置的基础上,自动生成其它的地图元素。

代码如下:

 // 产生随机位置的方法private Vector3 CreateRandomPosition() // 列表中没有这个位置,才能产生{while(true){// 不生成x=-13,13(变为10)这两列,y=-8,8这两行的位置Vector3 createPosition = new Vector3( Random.Range(-9,10), Random.Range(-7,8), 0); // x y z,Random.Range(a,b)中b的实际值是b-1if(!HasThePosition(createPosition)){ return createPosition; // 列表中没有的位置就返回 }// false 则继续循环}}

⭐️分步介绍(结合代码)

Audio.cs

  • 目的:调用音效
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Audio : MonoBehaviour
{public AudioClip hitAudio;public void PlayAudio(){AudioSource.PlayClipAtPoint(hitAudio, transform.position);}
}

Born.cs

  • 目的:让特效播放一段时间后自我销毁,产生玩家
  • 思路:首先引用玩家playerPrefab,新建一个敌人的数组作为敌人预制体的列表,并设置bool变量判断子弹是谁产生的。游戏一开始时,调用延时Born方法,经过延时销毁出生特效。判断是否是玩家,是则产生玩家,不是就定义一个随机数,随机生成2种敌人中的1种。
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Born : MonoBehaviour
{public GameObject playerPrefab; // 先拿一下玩家的引用public GameObject[] enemyPrefabList; // 新建一个敌人的数组:敌人预制体的列表public bool createPlayer; // 为了判断子弹是谁产生的(初始默认为敌人的)// Start is called before the first frame updatevoid Start(){Invoke("BornTank", 1.0f); // 让游戏一开始调用一下延时Born方法Destroy(gameObject, 1.0f); // 经过0.8f延时0.8f销毁出生特效}private void BornTank(){if(createPlayer) // ture则产生玩家{Instantiate(playerPrefab, transform.position, Quaternion.identity);}else // 敌人有两种,定义一个随机数{int num = Random.Range(0,2); // 0 1(整型情况包含前两个)Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);}}
}

Bullet.cs

  • 目的:模拟子弹和相关物体的碰撞效果
  • 思路:首先给子弹一个速度,这个速度要适中设置,建议和玩家移动速度相同。设置一个bool变量 isPlayerBullet(默认false,不是敌人的子弹),再分6类完善子弹碰撞检测的方法
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class bullet : MonoBehaviour
{public float moveSpeed = 10;public bool isPlayerBullet; // 默认false,不是敌人的子弹void Update(){transform.Translate(transform.up * moveSpeed * Time.deltaTime, Space.World); //让子弹沿着自身所在Y轴移动}//子弹碰撞检测的方法private void OnTriggerEnter2D(Collider2D collision) {switch (collision.tag){case "Tank":if (!isPlayerBullet) // 玩家碰到敌人的子弹{collision.SendMessage("Die");  // 玩家死亡一次Destroy(gameObject); // 玩家死亡,自身子弹销毁}break;case "Heart":collision.SendMessage("Die"); // 老家死亡Destroy(gameObject); // 子弹碰老家,子弹销毁break;case "Enemy":if(isPlayerBullet) // 敌人碰到玩家的子弹{collision.SendMessage("Die");  // 敌人死亡一次Destroy(gameObject); // 敌人死亡,自身子弹销毁}break;case "Wall":Destroy(collision.gameObject); // 子弹碰到,墙就销毁Destroy(gameObject); // 子弹碰墙,子弹也销毁break;case "Barrier":if(isPlayerBullet) // 玩家的子弹才有音效{collision.SendMessage("PlayAudio"); }Destroy(gameObject); // 子弹碰到不可销毁的障碍(铁墙和空气墙),子弹自身销毁break;default:break;}}
}

Enemy.cs

  • 目的:实现敌方坦克的攻击、移动、死亡操作并优化 敌人(Enemy) 的AI
  • 思路:这里要用到精灵渲染器,我们要考虑子弹的旋转角度、敌方坦克上下左右的移动操作,攻击的CD、改变方向的时间计时器以及攻击、移动和死亡的具体方法的实现。最后,为了使玩家获得更加流畅舒适的体验,我们要优化 敌人(Enemy) 的AI。
  • Tips:我们要用到 void FixedUpdate() 这个生命周期函数,它也叫固定物理帧,保证在每一秒都匀称的情况下执行...
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Enemy : MonoBehaviour
{//属性值public float moveSpeed = 3;private Vector3 bulletEulerAngles; // 子弹应该旋转的角度private float v = -1;private float h;//引用private SpriteRenderer sr;public Sprite[] tankSprite; // 表示(上 右 下 左)方向;因为要改变精灵的值,所以设一个精灵数组(也就是拿一个和精灵值同类型的属性)public GameObject bulletPrefab;public GameObject explosionPrefab;//计时器private float timeVal; // 攻击CD(计时器)private float timeValChangeDirection; // 改变方向的时间计时器(一开始若设为4是为了使其已出现就移动)private void Awake() // 一般的引用在awake中赋值比较好,因为所有属性的确定和引用都应该在游戏物体一开始的时候就拿到{sr = GetComponent<SpriteRenderer>(); // 拿到了精灵渲染的组件// 接下来去控制它的图片属性就可以了}void Update(){// 攻击的时间间隔if (timeVal >= 3f){}else{}}void FixedUpdate() // 生命周期函数,也叫固定物理帧,是在每一秒都匀称的情况下执行的{Move();}//坦克的攻击方法public void Attack(){//子弹产生的角度:当前坦克的角度+子弹应该旋转的角度(rotation中的欧拉角要转为四元数的形式表示角度)//子弹预制体 坦克位置 旋转角timeVal = 0;}// 坦克的移动方法private void Move() // 把移动代码封装成 Move()函数{// 下面的敌人AI只是为了控制h和v的值,下面和player一样根据值选择图片if(timeValChangeDirection >= 4) // 攻击一次后改变方向{int num = Random.Range(0, 8); // 多定义4个,为了让朝下的概率变大if(num > 5) // 向下(确保概率较大){}else if(num == 0) // 向上(确保概率较小){}else if (num > 0 && num <=2) // 向左{}else if (num > 2 && num <= 4) // 向右{}timeValChangeDirection = 0; // 归零防止鬼畜运动}else{// 因为move()的方法是放在void FixedUpdate()里面的 }//控制玩家的移动,Vector3.right 表示X轴方向的移动,Y轴是up,Z轴是forwardif (v < 0){sr.sprite = tankSprite[2];bulletEulerAngles = new Vector3(0, 0, -180);}else if (v > 0){sr.sprite = tankSprite[0];bulletEulerAngles = new Vector3(0, 0, 0);}if (v != 0) // 确保按照上下移动的同时不能进行左右移动{ return;}transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World); //Time.deltaTime:按每秒移动;逗号右边的第二个方向是以世界坐标轴的方向if (h < 0){}else if (h > 0){}}// 坦克的死亡方法private void Die(){// 敌人每次死亡,就让得分+1PlayerManager.Instance.playerScore++;// 产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}//优化Enemy的AI:若敌人相碰,顺时针旋转一个角度,这样能避免扎堆private void OnCollisionEnter2D(Collision2D collision) // 坦克是碰撞检测{if(collision.gameObject.tag=="Enemy"){// 时间瞬间达到4,即刻旋转}}
}

Explosion.cs

  • 目的:实现爆炸效果
  • 思路:这里的爆炸效果是刚出生的爆炸特效,持续短暂时间后消失就好,也就是只作用一小段时间
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Explosion : MonoBehaviour
{void Start(){Destroy(gameObject, 0.167f);}
}

Heart.cs

  • 目的:模拟 老家(Heart)
  • 思路:开始的时候就获取一下精灵渲染器组件,一旦触发老家死亡效果,就更换为老家被破坏时的图片,并附加爆炸特效。被击中的时候要调用一下 dieAudio音效。
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Heart : MonoBehaviour
{private SpriteRenderer sr;public Sprite BrokenSprite; // 为了获取老家(Heart)被破坏时的图片public GameObject explosionPrefab; // 拿一下爆炸效果的引用public AudioClip dieAudio;void Start(){sr = GetComponent<SpriteRenderer>(); // 开始的时候就获取一下精灵渲染器组件}public void Die(){// 更换图片:一旦触发老家死亡效果,就更换为老家被破坏时的图片// 产生爆炸特效PlayerManager.Instance.isDefeat = true; // 被击中// 在某个点调用一下dieAudio}
}

MapCreation.cs

  • 目的:地图实例化
  • 思路:我们在已知固定位置的地方手动生成,并将它们放在一个列表中,其他的位置用随机生成位置的方法生成地图,这样每次玩家进入游戏的时候,就是一张崭新的地图了,这就丰富了游戏的多样性和可玩性。我们将敌人位置的生成也放在这部分代码中。
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MapCreation : MonoBehaviour // 地图实例化
{// 用来装饰初始化地图所需物体的数组// 0.老家 1.墙 2.障碍 3.出生效果 4.河流 5.草 6.空气墙public GameObject[] item;// 已经有东西的位置列表private List<Vector3> itemPositionList = new List<Vector3>();private void Awake(){InitMap();}private void InitMap(){// 实例化老家(CreateItem其实还是用的Instantiate的方法)CreateItem(item[0], new Vector3(0, -8, 0), Quaternion.identity); // Quaternion.identity:无旋转//用墙把老家围起来CreateItem(item[1], new Vector3(-1, -8, 0), Quaternion.identity);CreateItem(item[1], new Vector3(1, -8, 0), Quaternion.identity);for (int i = -1; i < 2; i++){CreateItem(item[1], new Vector3(i, -7, 0), Quaternion.identity);}// 实例化外围墙 x=-14,14(变为11),y=-9,9for (int i = -11; i < 12; i++) //最上面一行{CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);}for (int i = -11; i < 12; i++) //最下面一行{CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);}for (int i = -8; i < 9; i++) //最左面一行{CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);}for (int i = -8; i < 9; i++) //最右面一行{CreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);}// 初始化玩家(通过实例化出生特效实例化玩家)GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity); // 产生出生特效go.GetComponent<Born>().createPlayer = true;// 特效上的bool值设置为true:产生玩家// 产生敌人(在固定的三个位置先产生,之后每隔一段时间在三个位置随机产生)CreateItem(item[3], new Vector3(-10, 8, 0), Quaternion.identity);CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);InvokeRepeating("CreateEnemy", 4, 5);// 实例化地图for (int i = 0; i < 60; i++){CreateItem(item[1], CreateRandomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[2], CreateRandomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[4], CreateRandomPosition(), Quaternion.identity);}for (int i = 0; i < 20; i++){CreateItem(item[5], CreateRandomPosition(), Quaternion.identity);}}private void CreateItem(GameObject createGameObject,Vector3 createPosition,Quaternion createRotation) // 封装一个方法:使播放时Hierarchy菜单下的东西不散落{// 根据上面的参数实例化游戏物体// Parent是当前的游戏物体// 把所有出现过的物体位置存进位置列表}// 产生随机位置的方法private Vector3 CreateRandomPosition() // 列表中没有这个位置,才能产生{while(true){// 不生成x=-13,13(变为10)这两列,y=-8,8这两行的位置Vector3 createPosition = new Vector3( Random.Range(-9,10), Random.Range(-7,8), 0); // x y z,Random.Range(a,b)中b的实际值是b-1if(!HasThePosition(createPosition)){ return createPosition; // 列表中没有的位置就返回 }// false 则继续循环}}// 用来判断位置列表中是否有这个位置private bool HasThePosition(Vector3 createPos){for (int i = 0; i < itemPositionList.Count; i++) // 遍历当前的位置列表{if(createPos == itemPositionList[i]) // 如果随机产生位置的值等于当前列表某个位置的值{return true;}}return false;}// 产生敌人的方法private void CreateEnemy(){int num = Random.Range(0, 3); // 0 1 2Vector3 EnemyPos = new Vector3(); // 装随机产生的位置:向量/坐标if (num == 0){}else if (num == 1){}else {}CreateItem(item[3], EnemyPos, Quaternion.identity);}
}

Option.cs

  • 目的:选项监听实现
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;public class Option : MonoBehaviour
{private int choice = 1;public Transform posOne;public Transform posTwo;// Update is called once per framevoid Update(){// 监听开始界面上下移动的选项if (Input.GetKeyDown(KeyCode.W)){choice = 1;transform.position = posOne.position;}else if (Input.GetKeyDown(KeyCode.S)){choice = 2;transform.position = posTwo.position;}if (choice==1 && Input.GetKeyDown(KeyCode.Space)){SceneManager.LoadScene(1); // 加载 Main 场景}}
}

Player.cs

  • 目的:模拟玩家坦克Player
  • 思路:玩家坦克Player 的实现可以借鉴 敌方坦克Enemy
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Player : MonoBehaviour {//属性值public float moveSpeed = 3;private Vector3 bulletEulerAngles; // 子弹应该旋转的角度private float timeVal; // 攻击CD(计时器)private float defendTimeVal = 3; // 无敌CD(计时器)private bool isDefended = true; // 无敌状态//引用// 拿到渲染器// 拿到需要用到的图片,(上 右 下 左)方向;因为要改变精灵的值,所以设一个精灵数组(也就是拿一个和精灵值同类型的属性)public GameObject bulletPrefab;public GameObject explosionPrefab;public GameObject defendEffectPrefab;// 控制音效的播放// 拿到音效播放的资源private void Awake() // 一般的引用在awake中赋值比较好,因为所有属性的确定和引用都应该在游戏物体一开始的时候就拿到{// 拿到了精灵渲染的组件// 接下来去控制它的图片属性就可以了}void Update(){// 无敌CDif(isDefended){defendEffectPrefab.SetActive(true); // 控制无敌状态时护盾打开defendTimeVal -= Time.deltaTime;if(defendTimeVal <= 0){isDefended = false;// 控制无敌状态时护盾关闭}}}private void FixedUpdate() {// 生命周期函数,也叫固定物理帧,是在每一秒都匀称的情况下执行的if(PlayerManager.Instance.isDefeat){return; // true则return:游戏失败,禁止玩家所有操作}Move();// 攻击CDif (timeVal >= 0.4f){Attack();}else{timeVal += Time.fixedDeltaTime;}}//坦克的攻击方法public void Attack(){if() //若检测到玩家输入为空格键{//子弹产生的角度:当前坦克的角度+子弹应该旋转的角度(rotation中的欧拉角要转为四元数的形式表示角度)//子弹预制体 坦克位置 旋转角timeVal = 0;}}// 坦克的移动方法private void Move() // 把移动代码封装成 Move()函数{// 监听玩家垂直轴值的输入transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);if (v < 0) {}else if (v > 0) {}// v和h不为0,播放...音效 (在判断v是否为0之前判断是考虑了它的优先级)if(Mathf.Abs(v)>0.05f){// 若音效播放时又调用,声音会很杂,所以要判断...if(!moveAudio.isPlaying){moveAudio.Play();}}if (v != 0) { // 确保按照上下移动的同时不能进行左右移动return;}//监听玩家水平轴值的输入h来控制在X轴上的位移的方向,按右方向为1,左为-1//控制玩家的移动,Vector3.right 表示X轴方向的移动,Y轴是up,Z轴是forwardtransform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World); //Time.deltaTime:按每秒移动;逗号右边的第二个方向是以世界坐标轴的方向if (h < 0) {}else if (h > 0) {}if (Mathf.Abs(h) > 0.05f){moveAudio.clip = tankAudio[1]; if (!moveAudio.isPlaying){moveAudio.Play();}}else{moveAudio.clip = tankAudio[0];if (!moveAudio.isPlaying){moveAudio.Play();}}}// 坦克的死亡方法private void Die(){// 是否处于无敌状态if (isDefended){return;}// 击中的话,就让玩家管理里面的属性变为truePlayerManager.Instance.isDead = true;// 产生爆炸特效Instantiate(explosionPrefab, transform.position, transform.rotation);//死亡Destroy(gameObject);}}

PlayerManager.cs

  • 目的:玩法管理和UI设计
  • 代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.UI; // 为了更新 UI,拿一下它的引用,使用 UI,就要拿一下Unity的运营空间
using UnityEngine.SceneManagement;public class PlayerManager : MonoBehaviour
{//属性值public int lifeValue = 3;public int playerScore = 0;public bool isDead;public bool isDefeat;//引用public GameObject born;public Text playerScoreText;public Text playerLifeValueText;public GameObject isDefeatUI; // 拿一下游戏物体的引用//单例private static PlayerManager instance;public static PlayerManager Instance { get => instance; set => instance = value; }private void Awake(){Instance = this;}// Update is called once per framevoid Update() // 在其中实时监听一些状态{if(isDefeat) // 失败的话{isDefeatUI.SetActive(true); // 让失败的图片显示return;}if(isDead) // 如果死亡{Recover();}// 实时更新消灭敌人的显示和生命值playerScoreText.text = playerScore.ToString(); // .ToString():把int转化为字符串playerLifeValueText.text = lifeValue.ToString();}private void Recover(){if (lifeValue<=0){// 游戏失败,返回主界面isDefeat = true;Invoke("ReturnToTheMainMenu", 3); // 延时3s调用这个方法}else{lifeValue --;GameObject go = Instantiate(born, new Vector3(-2, -7.9f, 0), Quaternion.identity); // 接收born的脚本go.GetComponent<Born>().createPlayer = true;isDead = false;}}private void ReturnToTheMainMenu(){SceneManager.LoadScene(0); // 返回开始界面}}

完结,撒花❀~

Unity3D | 经典小游戏Battle City相关推荐

  1. python经典小游戏-用Python设计一个经典小游戏:猜大小

    码农那点事儿 关注我们,一起学习进步 本文主要介绍如何用Python设计一个经典小游戏:猜大小. 游戏规则: 初始本金是1000元,默认赔率是1倍,赢了,获得一倍金额,输了,扣除1倍金额. 玩家选择下 ...

  2. 20行python代码的入门级小游戏-用Python设计一个经典小游戏

    本文主要介绍如何用Python设计一个经典小游戏:猜大小. 在这个游戏中,将用到前面我介绍过的所有内容:变量的使用.参数传递.函数设计.条件控制和循环等,做个整体的总结和复习. 游戏规则: 初始本金是 ...

  3. python经典小游戏-用Python设计一个经典小游戏

    本文主要介绍如何用Python设计一个经典小游戏:猜大小. 在这个游戏中,将用到前面我介绍过的所有内容:变量的使用.参数传递.函数设计.条件控制和循环等,做个整体的总结和复习. 游戏规则: 初始本金是 ...

  4. python拼图游戏代码_GitHub 上哪些勾起回忆的经典小游戏(Python)

    经常有人问我 Python 能开发游戏吗?今天就直接给大家推荐一个汇集多款经典小游戏的Github项目:Free Python Games. 项目地址:grantjenks/free-python-g ...

  5. c语言经典游戏,C语言——经典小游戏——打砖块

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 C语言--经典小游戏--打砖块 玩法:按A与D控制球拍的移动,按S暂停游戏 百度网盘下载:http://pan.baidu.com/s/1o64ECTc ...

  6. Windows经典小游戏--扫雷精装版

    Windows经典小游戏–扫雷精装版 最开始玩的电脑游戏就是蜘蛛纸牌和扫雷了,那时候觉得很神奇的事情现在自己也可以做了.下面就展示一下C语言扫雷的代码. 首先创建一个"扫雷"的项目 ...

  7. 经典小游戏(密室逃脱全集+答案)

    经典小游戏--密室逃脱全集(有答案) 转自月影梦魇原来玩过的一个小游戏 最近想起来想发给大家玩一下   有一点小难度的哦   看谁可以出得来密室   一共有三个密室 这三个游戏是有一点相连的 蓝色房间 ...

  8. Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk

    Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk 程序依赖:pygame2.0.1, pymunk5.5.0 直接运行main.py 完整代码下载地址:Python版经典小游戏 ...

  9. C#winform 经典小游戏贪吃蛇V1.0(一)

    关于V1.0   为什么我给这个版本定义为V1.0嘞,因为在这个版本中仅仅实现了蛇的自动行进,按键对蛇的行进方向的操作和吃掉食物蛇身的增长等操作. 但是任何事情都必须一步一步来,当我们完成这个乞丐版的 ...

  10. c++编写手机小游戏代码_经典小游戏大集合(C++ 源码)

    [实例简介] 五子棋 贪吃蛇 俄罗斯方块 黑白棋 连连看 推箱子 扫雷等7个小游戏 C++源码 VC6.0 下编译运行. [实例截图] [核心代码] 经典小游戏大集合(C源码) └── 经典小游戏大集 ...

最新文章

  1. 2021-12-09把文件夹1中的与文件夹2里同名图片删除或者保存至另一个文件夹
  2. Java集合源码分析(二)ArrayList
  3. MPLS 典型应用场景——Vecloud
  4. 3层、5层、3层一个卷积核BP神经网络性能比较
  5. 【python图像处理】彩色映射(续篇)
  6. BZOJ4066:简单题(K-D Tree)
  7. nineoldandroid使用_nineoldandroid 详细使用并且实现drawerlayout侧滑动画
  8. 计算机绘制轴类零件图,轴类零件工序图自动绘制的方法和系统研究
  9. 梯形图 c语言代码生成,PLC梯形图中内嵌C语言编程的实现
  10. Genymotion - 强大好用高性能的 Android 模拟器 (在电脑流畅运行APK安卓软件游戏的利器)...
  11. cesium坡度坡向分析_综合分析地理空间,科学规划乡村区域
  12. java缓存_使用Redis和Java进行数据库缓存
  13. 电脑怎么分盘win10_电脑时间不对怎么办?Win10电脑时间总是不对的解决方法_电脑故障...
  14. hadoop(八) - hbase集群环境搭建
  15. mysql5启动错误1067_win7 64位 mysql5.5启动服务报错无法启动,错误1067
  16. Hibernate的like用法
  17. [转载] python 中的时间,日期,时间戳互相转换
  18. docker build -t_利用Dockerfile自定义镜像-图解轻松学Dockeramp;K8S
  19. 完全二叉树的节点数量
  20. android 蓝牙转串口_android自带的示例程序 BluetoothChat 变蓝牙串口助手

热门文章

  1. php接收post数据 json数据,PHP接收post数据并解析json的简单实例
  2. HD Tune Pro硬盘检测工具官方版
  3. 【吃豆游戏----HTML+JS+CSS等实现,效果+源代码】
  4. 线性代数知识点整理(自用)
  5. 阿里再“牵手”中国邮政 民营快递或共享资源?
  6. 安卓bochs安装linux教程,Ubuntu 14.04 LTS 安装和配置Bochs
  7. KVM虚拟化技术浅析
  8. word计算机相乘公式,怎么使用Word复制乘积公式
  9. Windows环境下Redis安装与配置的两种方式
  10. 计算机网络第七版课后习题答案(第一章)(20210321)