zoukankan      html  css  js  c++  java
  • PetGenie

      大概六、七年前当我还在学 Asphyre 的时候,有看过一个以之编写的类似对对碰的“宠物对对碰”小游戏,虽然很简单,但我当时还是小小的沉溺过数个小时。而不久前,在闲逛论坛时无意看到了个以 FireMonkey 为所谓框架编写的另一款对对碰小游戏 GemGenie(需翻墙查看),由于其以 Delphi 开发,抱着看看 Delphi 现阶段对移动游戏开发的支持程度如何了,我下了个安装包,在我的华为荣耀U9508上跑了下。

      结果当然很失望,我很难比较流畅的游戏。这个 FireMonkey 出来已 5 年左右了,还是半个玩具。

      我自然比较倾向这个游戏的作者水平不会差(到哪去),所以不流畅的原因我想不归结于 FireMonkey 都难,而这玩意确实也一直备受诟病。

      当然,某司宣称过 FireMonkey 并非针对游戏开发而提供。

      那就让还用某司开发工具的人用某司的玩具工具去开发应用 APP 吧。

      大概七、八个月前,我在学 Unity3D 的时候想练练手,刚好那时候 Unity3D 已开始官方支持 2D 开发,所以那时我就用 Unity2D 重写了前文提及的“宠物对对碰”游戏。不过那时候我所学还非常浅,虽然确实重写出了这个游戏,但效果却很不尽如人意,如下:

      像这样简单的游戏,如此多的 Draw Calls 显然是不可接受的(我应该正确使用 Sprite Packer 打包了图片资源)。

      那时我是通过 OnGUI 及 Graphics.DrawTexture 等来实现绘制等相关的,此做法明显还比较原始:

    void OnGUI() {
    		if(Event.current.type.Equals(EventType.Repaint)) {			
    			// 绘制背景
    			DrawBkgrd();
    
    			// 绘制剩余时间条
    			DrawTimeBar();
    
    			// 绘制得分
    			DrawScore();
    
    			// 绘制所有头像
    			DrawSpriteTextures();
    			
    			// 绘制游戏信息
    			DrawGameCopyright();
    		}
    	}
    
    	void DrawBkgrd() {
    		Graphics.DrawTexture(new Rect((Screen.width - cBkgrdW) / 2, (Screen.height - cBkgrdH) / 2, 386, 506), 
    		                     bkgrdTexture, new Rect(0.0f, 0.0f, 1.0f, 1.0f), 0, 0, 0, 0, null);
    	}
    
    	void DrawTimeBar() {
    		Graphics.DrawTexture(new Rect(41 + (Screen.width - cBkgrdW) / 2, 25 + (Screen.height - cBkgrdH) / 2, time / cTimeMax * 300, 10), 
    		                     timeTexture, new Rect(0.0f, 0.0f, time / cTimeMax, 1.0f), 0, 0, 0, 0, null);
    	}
    

      

      这几天有些闲,我索性想重新实现下(绘制相关),于是开搞。

      ——游戏首先最好有个名字,既然有 GemGenie,那这个就叫 PetGenie(宠物精灵)吧!

      在重新导入及打包资源、废了些脑力回看及修改之前的代码后,得到了看起来似乎比之前的版本要优化的结果了:

      这个版本看起来在绘制上应该不会有压力了:)

      导入手机,跑起来(如丝般顺滑),如下:

      这个版本里,以如下逻辑替代了之前版本的绘制相关代码:

    void Update () {
    		if (!isGameOver) {
    			if ((!isMoving) || (!isUpdating)) {
    				timeLeft -= Time.deltaTime;
    			}			
    			
    			if (timeLeft <= 0) {
    				isGameOver = true;
    				audioSrc.PlayOneShot(gameOverClip);
    				Application.LoadLevel("FailScene");
    			}
    
    			if (score >= cScoreMax) {
    				Application.LoadLevel("WinScene");
    			}
    		}
    		else {
    			if (audioSrc.isPlaying) {
    				audioSrc.Stop();
    			}
    		}
    		
    		if (Input.GetKey(KeyCode.Escape)) {
    			isGameOver = true;
    			Application.Quit();
    		}
    
    		// 检测输入信息
    		DetectInput();
    
    		// 更新精灵宠物信息
    		UpdateGenies();
    
    		// 更新剩余时间条大小&位置
    		UpdateTimeBar();
    
    		// 更新得分
    		UpdateScore();
    	}
    
    private void UpdateTimeBar() {
    		// 横向缩放
    		timeLeftTransform.localScale = new Vector3(timeLeft / cTimeMax, timeLeftTransform.localScale.y, timeLeftTransform.localScale.z);
    		// 改变 X 坐标(前一步的缩放是双方向内缩,所以这里要除以2)
    		timeLeftTransform.position = new Vector3(cTimeBarGapLeft + 5.12f * (timeLeftTransform.localScale.x - 1.0f) / 2, timeLeftTransform.position.y, timeLeftTransform.position.z);
    	}
    

      而这些逻辑的实现似乎有好几种方法,为简单起见(毕竟只是业余弄弄),我选了其中最简单的:摆控件(反正控件又不多)。

      这样的开发方式似乎也正是 Unity3D 的所长。

      这是最终的工程APK 文件。代码比较凌乱,整个设计也有很多改进之处,此仅为练手而已。

      注:

      1)、我手边没有比较好看的美术资源,也不会 PS作图,所以游戏看起来比较挫:)

      2)、这个网页是个很好的学习去处,包含 Uinty3D 及 Cocos 等相关资源(可能需要翻墙)。

  • 相关阅读:
    Variant 数组
    socket c/s分佈式編程
    多線程幾個方法說明
    hash表的使用
    MIS系统权限控制的一个简便方法
    git 使用总结
    让 VAGRANT 启动并运行起来
    深入理解 Laravel 中 config 配置加载原理
    Vagrant入门
    php开发APP接口(总结一)
  • 原文地址:https://www.cnblogs.com/ecofast/p/4097806.html
Copyright © 2011-2022 走看看