用Unity打造愤怒的小鸟游戏

愤怒的小鸟游戏开发实现

要实现一个《愤怒的小鸟》游戏,有多种技术方案可选,主要基于不同的游戏引擎和编程语言。下面我将详细介绍几种主流实现方式,并提供核心代码示例。

一、技术方案对比

方案 使用引擎/框架 编程语言 适合平台 开发复杂度 物理引擎
方案1 Unity3D C# 跨平台(PC、移动端) 中等 Unity内置物理引擎
方案2 Cocos2d-x C++/JavaScript 跨平台 中等 Box2D
方案3 HTML5 Canvas JavaScript Web浏览器 中等 Box2DWeb/pymunk
方案4 PyGame + pymunk Python PC桌面 较低 pymunk

二、Unity3D实现方案(推荐)

Unity是最流行的游戏开发引擎之一,内置强大的物理系统,非常适合开发《愤怒的小鸟》这类物理游戏。

1. 项目设置与基础场景

csharp 复制代码
// CameraController.cs - 相机控制脚本
using UnityEngine;

public class CameraController : MonoBehaviour
{
    public Transform target; // 跟随的目标(小鸟)
    public float smoothSpeed = 0.125f;
    public Vector3 offset = new Vector3(0, 0, -10);
    
    void LateUpdate()
    {
        if (target != null)
        {
            Vector3 desiredPosition = target.position + offset;
            Vector3 smoothedPosition = Vector3.Lerp(
                transform.position, 
                desiredPosition, 
                smoothSpeed
            );
            transform.position = smoothedPosition;
        }
    }
}

2. 小鸟物理控制

csharp 复制代码
// BirdController.cs - 小鸟控制脚本 
using UnityEngine;

public class BirdController : MonoBehaviour
{
    public float maxDragDistance = 2.0f; // 最大拖拽距离
    public float launchForce = 10.0f;    // 发射力量
    public LineRenderer trajectoryLine;   // 轨迹线渲染器
    
    private bool isDragging = false;
    private Vector3 startPosition;
    private Rigidbody2D rb;
    private SpringJoint2D springJoint;
    
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        springJoint = GetComponent<SpringJoint2D>();
        startPosition = transform.position;
    }
    
    void OnMouseDown()
    {
        if (!isDragging)
        {
            isDragging = true;
            rb.isKinematic = true;
        }
    }
    
    void OnMouseDrag()
    {
        if (isDragging)
        {
            Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            mousePos.z = 0;
            
            // 限制拖拽范围
            Vector3 dragDirection = (startPosition - mousePos).normalized;
            float dragDistance = Vector3.Distance(mousePos, startPosition);
            dragDistance = Mathf.Min(dragDistance, maxDragDistance);
            
            transform.position = startPosition + dragDirection * dragDistance;
            
            // 显示轨迹线
            UpdateTrajectory();
        }
    }
    
    void OnMouseUp()
    {
        if (isDragging)
        {
            isDragging = false;
            rb.isKinematic = false;
            
            // 计算发射方向
            Vector3 launchDirection = (startPosition - transform.position).normalized;
            rb.AddForce(launchDirection * launchForce, ForceMode2D.Impulse);
            
            // 禁用弹簧关节
            if (springJoint != null)
                springJoint.enabled = false;
            
            // 隐藏轨迹线
            if (trajectoryLine != null)
                trajectoryLine.enabled = false;
        }
    }
    
    void UpdateTrajectory()
    {
        // 使用物理模拟预测轨迹
        if (trajectoryLine != null)
        {
            trajectoryLine.enabled = true;
            trajectoryLine.positionCount = 20;
            
            Vector3[] positions = new Vector3[20];
            Vector3 currentPos = transform.position;
            Vector3 velocity = (startPosition - transform.position).normalized * launchForce;
            
            for (int i = 0; i < 20; i++)
            {
                positions[i] = currentPos;
                velocity += Physics2D.gravity * Time.fixedDeltaTime;
                currentPos += velocity * Time.fixedDeltaTime;
            }
            
            trajectoryLine.SetPositions(positions);
        }
    }
}

3. 弹弓实现

csharp 复制代码
// Slingshot.cs - 弹弓控制脚本 
using UnityEngine;

public class Slingshot : MonoBehaviour
{
    public Transform leftPoint;    // 左弹弓点
    public Transform rightPoint;   // 右弹弓点
    public Transform centerPoint;  // 中心点(小鸟初始位置)
    public GameObject birdPrefab;  // 小鸟预制体
    
    private GameObject currentBird;
    
    void Start()
    {
        SpawnNewBird();
    }
    
    void SpawnNewBird()
    {
        if (birdPrefab != null && centerPoint != null)
        {
            currentBird = Instantiate(birdPrefab, centerPoint.position, Quaternion.identity);
            
            // 添加弹簧关节连接到弹弓
            SpringJoint2D springJoint = currentBird.AddComponent<SpringJoint2D>();
            springJoint.connectedAnchor = centerPoint.position;
            springJoint.distance = 0.1f;
            springJoint.dampingRatio = 1f;
            springJoint.frequency = 4f;
        }
    }
    
    void Update()
    {
        // 绘制弹弓橡皮筋
        if (currentBird != null && isDragging)
        {
            DrawRubberBand();
        }
    }
    
    void DrawRubberBand()
    {
        LineRenderer lineRenderer = GetComponent<LineRenderer>();
        if (lineRenderer != null)
        {
            lineRenderer.positionCount = 3;
            lineRenderer.SetPosition(0, leftPoint.position);
            lineRenderer.SetPosition(1, currentBird.transform.position);
            lineRenderer.SetPosition(2, rightPoint.position);
        }
    }
}

4. 障碍物与猪的物理属性

csharp 复制代码
// Obstacle.cs - 障碍物脚本
using UnityEngine;

public class Obstacle : MonoBehaviour
{
    public enum MaterialType
    {
        Wood,
        Stone,
        Ice,
        Glass
    }
    
    public MaterialType material = MaterialType.Wood;
    public float health = 100f;
    
    void Start()
    {
        // 根据材质设置物理属性 
        Rigidbody2D rb = GetComponent<Rigidbody2D>();
        Collider2D collider = GetComponent<Collider2D>();
        
        switch (material)
        {
            case MaterialType.Wood:
                rb.mass = 1.0f;
                rb.drag = 0.5f;
                break;
            case MaterialType.Stone:
                rb.mass = 2.5f;
                rb.drag = 0.8f;
                break;
            case MaterialType.Ice:
                rb.mass = 0.8f;
                rb.drag = 0.1f;
                break;
            case MaterialType.Glass:
                rb.mass = 0.5f;
                rb.drag = 0.3f;
                break;
        }
    }
    
    void OnCollisionEnter2D(Collision2D collision)
    {
        // 计算碰撞伤害
        float impactForce = collision.relativeVelocity.magnitude;
        float damage = impactForce * 10f;
        
        health -= damage;
        
        if (health <= 0)
        {
            DestroyObstacle();
        }
    }
    
    void DestroyObstacle()
    {
        // 播放粒子效果
        ParticleSystem breakEffect = GetComponentInChildren<ParticleSystem>();
        if (breakEffect != null)
        {
            breakEffect.Play();
        }
        
        // 延迟销毁
        Destroy(gameObject, 0.5f);
    }
}

// PigController.cs - 猪的控制脚本
using UnityEngine;

public class PigController : MonoBehaviour
{
    public float health = 50f;
    public GameObject deathEffect;
    
    void OnCollisionEnter2D(Collision2D collision)
    {
        // 根据碰撞速度计算伤害
        float impactForce = collision.relativeVelocity.magnitude;
        
        if (impactForce > 2f)
        {
            float damage = impactForce * 5f;
            TakeDamage(damage);
        }
    }
    
    void TakeDamage(float damage)
    {
        health -= damage;
        
        if (health <= 0)
        {
            Die();
        }
    }
    
    void Die()
    {
        // 播放死亡效果
        if (deathEffect != null)
        {
            Instantiate(deathEffect, transform.position, Quaternion.identity);
        }
        
        // 增加分数
        ScoreManager.Instance.AddScore(1000);
        
        Destroy(gameObject);
    }
}

三、HTML5 + JavaScript实现方案

使用HTML5 Canvas和Box2D物理引擎,适合Web平台开发。

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>愤怒的小鸟 - HTML5版</title>
    <style>
        canvas {
            border: 1px solid #000;
            display: block;
            margin: 20px auto;
            background: #87CEEB;
        }
        #gameInfo {
            text-align: center;
            font-family: Arial, sans-serif;
        }
    </style>
</head>
<body>
    <div id="gameInfo">
        <h2>愤怒的小鸟</h2>
        <p>分数: <span id="score">0</span> | 剩余小鸟: <span id="birdsLeft">5</span></p>
    </div>
    <canvas id="gameCanvas" width="800" height="600"></canvas>
    
    <script>
        // 游戏主类 
        class AngryBirdsGame {
            constructor() {
                this.canvas = document.getElementById('gameCanvas');
                this.ctx = this.canvas.getContext('2d');
                this.score = 0;
                this.birdsLeft = 5;
                this.currentBird = null;
                this.isDragging = false;
                this.startPos = {x: 0, y: 0};
                this.endPos = {x: 0, y: 0};
                
                // 游戏对象数组
                this.birds = [];
                this.pigs = [];
                this.obstacles = [];
                
                this.init();
                this.gameLoop();
            }
            
            init() {
                // 创建弹弓
                this.createSlingshot();
                
                // 创建障碍物
                this.createObstacles();
                
                // 创建猪
                this.createPigs();
                
                // 创建小鸟
                this.createBird();
                
                // 绑定事件
                this.bindEvents();
            }
            
            createSlingshot() {
                // 绘制弹弓
                this.slingshot = {
                    x: 100,
                    y: 400,
                    width: 20,
                    height: 80
                };
            }
            
            createBird() {
                this.currentBird = {
                    x: this.slingshot.x,
                    y: this.slingshot.y,
                    radius: 15,
                    color: 'red',
                    velocity: {x: 0, y: 0},
                    launched: false
                };
            }
            
            createObstacles() {
                // 创建木箱障碍物
                for (let i = 0; i < 3; i++) {
                    this.obstacles.push({
                        x: 500 + i * 60,
                        y: 400,
                        width: 40,
                        height: 40,
                        type: 'wood',
                        health: 100
                    });
                }
            }
            
            createPigs() {
                this.pigs.push({
                    x: 550,
                    y: 440,
                    radius: 20,
                    health: 50,
                    color: 'green'
                });
            }
            
            bindEvents() {
                this.canvas.addEventListener('mousedown', (e) => {
                    const rect = this.canvas.getBoundingClientRect();
                    const mouseX = e.clientX - rect.left;
                    const mouseY = e.clientY - rect.top;
                    
                    // 检查是否点击了小鸟
                    const distance = Math.sqrt(
                        Math.pow(mouseX - this.currentBird.x, 2) + 
                        Math.pow(mouseY - this.currentBird.y, 2)
                    );
                    
                    if (distance < this.currentBird.radius && !this.currentBird.launched) {
                        this.isDragging = true;
                        this.startPos = {x: mouseX, y: mouseY};
                    }
                });
                
                this.canvas.addEventListener('mousemove', (e) => {
                    if (this.isDragging && this.currentBird && !this.currentBird.launched) {
                        const rect = this.canvas.getBoundingClientRect();
                        this.endPos = {
                            x: e.clientX - rect.left,
                            y: e.clientY - rect.top
                        };
                        
                        // 限制拖拽距离
                        const maxDistance = 100;
                        const dragX = this.startPos.x - this.endPos.x;
                        const dragY = this.startPos.y - this.endPos.y;
                        const distance = Math.sqrt(dragX * dragX + dragY * dragY);
                        
                        if (distance > maxDistance) {
                            const angle = Math.atan2(dragY, dragX);
                            this.endPos.x = this.startPos.x - Math.cos(angle) * maxDistance;
                            this.endPos.y = this.startPos.y - Math.sin(angle) * maxDistance;
                        }
                        
                        this.currentBird.x = this.endPos.x;
                        this.currentBird.y = this.endPos.y;
                    }
                });
                
                this.canvas.addEventListener('mouseup', () => {
                    if (this.isDragging && this.currentBird && !this.currentBird.launched) {
                        this.isDragging = false;
                        this.launchBird();
                    }
                });
            }
            
            launchBird() {
                // 计算发射速度和方向
                const deltaX = this.startPos.x - this.endPos.x;
                const deltaY = this.startPos.y - this.endPos.y;
                const power = 0.3; // 力量系数
                
                this.currentBird.velocity = {
                    x: deltaX * power,
                    y: deltaY * power
                };
                this.currentBird.launched = true;
                this.birdsLeft--;
                document.getElementById('birdsLeft').textContent = this.birdsLeft;
            }
            
            updateBird() {
                if (this.currentBird && this.currentBird.launched) {
                    // 应用重力
                    this.currentBird.velocity.y += 0.5;
                    
                    // 更新位置
                    this.currentBird.x += this.currentBird.velocity.x;
                    this.currentBird.y += this.currentBird.velocity.y;
                    
                    // 边界检查
                    if (this.currentBird.x > this.canvas.width || 
                        this.currentBird.y > this.canvas.height ||
                        this.currentBird.x < 0) {
                        this.createBird();
                    }
                    
                    // 碰撞检测
                    this.checkCollisions();
                }
            }
            
            checkCollisions() {
                // 与猪的碰撞
                this.pigs.forEach((pig, index) => {
                    const distance = Math.sqrt(
                        Math.pow(this.currentBird.x - pig.x, 2) + 
                        Math.pow(this.currentBird.y - pig.y, 2)
                    );
                    
                    if (distance < this.currentBird.radius + pig.radius) {
                        pig.health -= 30;
                        if (pig.health <= 0) {
                            this.pigs.splice(index, 1);
                            this.score += 1000;
                            document.getElementById('score').textContent = this.score;
                        }
                    }
                });
                
                // 与障碍物的碰撞
                this.obstacles.forEach((obstacle, index) => {
                    const birdLeft = this.currentBird.x - this.currentBird.radius;
                    const birdRight = this.currentBird.x + this.currentBird.radius;
                    const birdTop = this.currentBird.y - this.currentBird.radius;
                    const birdBottom = this.currentBird.y + this.currentBird.radius;
                    
                    const obstacleLeft = obstacle.x;
                    const obstacleRight = obstacle.x + obstacle.width;
                    const obstacleTop = obstacle.y;
                    const obstacleBottom = obstacle.y + obstacle.height;
                    
                    if (birdRight > obstacleLeft && 
                        birdLeft < obstacleRight && 
                        birdBottom > obstacleTop && 
                        birdTop < obstacleBottom) {
                        
                        obstacle.health -= 50;
                        if (obstacle.health <= 0) {
                            this.obstacles.splice(index, 1);
                        }
                    }
                });
            }
            
            draw() {
                // 清空画布
                this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
                
                // 绘制背景
                this.ctx.fillStyle = '#87CEEB';
                this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
                
                // 绘制地面
                this.ctx.fillStyle = '#8B4513';
                this.ctx.fillRect(0, 500, this.canvas.width, 100);
                
                // 绘制弹弓
                this.ctx.fillStyle = '#8B4513';
                this.ctx.fillRect(this.slingshot.x - 10, this.slingshot.y, 20, 80);
                this.ctx.fillRect(this.slingshot.x - 40, this.slingshot.y + 60, 80, 20);
                
                // 绘制拖拽线
                if (this.isDragging && this.currentBird && !this.currentBird.launched) {
                    this.ctx.beginPath();
                    this.ctx.moveTo(this.slingshot.x, this.slingshot.y);
                    this.ctx.lineTo(this.currentBird.x, this.currentBird.y);
                    this.ctx.strokeStyle = '#8B4513';
                    this.ctx.lineWidth = 3;
                    this.ctx.stroke();
                }
                
                // 绘制小鸟
                if (this.currentBird) {
                    this.ctx.beginPath();
                    this.ctx.arc(
                        this.currentBird.x, 
                        this.currentBird.y, 
                        this.currentBird.radius, 
                        0,

----

## 参考来源
- [21个测试高频面试题](https://blog.csdn.net/2301_79535618/article/details/146230496)
- [CSDN日报190911:Unity3D开发小游戏;常见的五种神经网络](https://blog.csdn.net/blogdevteam/article/details/100739839)
- [IOS cocos2d学习笔记-扉页](https://blog.csdn.net/banana_416432275/article/details/9717335)
- [Python 愤怒的小鸟代码实现(1):物理引擎pymunk使用](https://blog.csdn.net/marble_xu/article/details/102079236)
- [【Unity3D开发小游戏】《愤怒的小鸟》Unity开发教程](https://blog.csdn.net/q764424567/article/details/100726495)
- [html5游戏开发-愤怒的小鸟-开源讲座(一)-跳入弹出的小鸟](https://blog.csdn.net/lufy_legend/article/details/7765599)
相关推荐
上海云盾安全满满2 小时前
游戏版本,数据被盗如何预防
游戏
2301_780789662 小时前
游戏盾是如何防护各个重要的游戏端口呢
服务器·网络·人工智能·游戏·架构·零信任
开开心心就好2 小时前
这款PPT计时工具支持远程控制功能
前端·科技·游戏·edge·pdf·全文检索·powerpoint
雪儿waii11 小时前
Unity 中的 Resources 详解
unity·游戏引擎
开开心心就好19 小时前
无需安装的单机塔防游戏轻松畅玩
人工智能·游戏·pdf·音视频·智能家居·语音识别·媒体
开开心心就好19 小时前
这款工具批量卸载软件并清理残留文件
人工智能·游戏·音视频·语音识别·媒体·程序员创富·高考
谭欣辰19 小时前
C++ 控制台跑酷小游戏
c++·游戏
好家伙VCC20 小时前
**发散创新:用 Rust实现游戏日引擎核心模块——从事件驱动到多线程调度的实战
java·开发语言·python·游戏·rust
RReality1 天前
【Unity UGUI】Toggle / ToggleGroup 与 Dropdown
ui·unity·游戏引擎·图形渲染·材质