类银河恶魔城学习记录-Crash Course

类银河恶魔城学习记录-Crash Course

本文记录一下学习过程中照着教程敲的代码~

Enemy_Skeleton.cs

using UnityEngine;
//骷髅敌人
public class Enemy_Skeleton : Entity
{
    [Header("Move Info")]
    [SerializeField] private float moveSpeed;

    [Header("Player Detection")]
    [SerializeField] private float playerCheckDistance;
    [SerializeField] private LayerMask whatIsPlayer;

    private RaycastHit2D isPlayerDetected;
    bool isAttacking;
    protected override void Start()
    {
        base.Start();
    }

    protected override void Update()
    {
        base.Update();
        //只要检测到玩家
        if (isPlayerDetected)
        {
            if (isPlayerDetected.distance > 3)
            {
                rb.velocity = new Vector2(facingDir * moveSpeed * 1.5f, rb.velocity.y);
                Debug.Log("I see the Player!");
                isAttacking = false;
            }
            else
            {
                Debug.Log("Attaking " + isPlayerDetected.collider.gameObject.name);
                isAttacking = true;
            }
        }
        

        if (!isGrounded || isWallDetected)
            Flip();
        Movement();
    }

    private void Movement()
    {
        if(!isAttacking)
            rb.velocity = new Vector2(facingDir * moveSpeed, rb.velocity.y);
    }

    protected override void CheckCollision()
    {
        base.CheckCollision();
        isPlayerDetected = Physics2D.Raycast(transform.position, Vector2.right, playerCheckDistance * facingDir, whatIsPlayer);

    }
    protected override void OnDrawGizmos()
    {
        base.OnDrawGizmos();
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + playerCheckDistance * facingDir, transform.position.y));
    }
}


Entity.cs

using UnityEngine;
//实体类
public class Entity : MonoBehaviour
{
    protected Rigidbody2D rb;
    protected Animator anim;

    protected bool isGrounded;
    protected bool isWallDetected;

    [Header("Collision Info")]
    [SerializeField] protected LayerMask whatIsGround;
    [SerializeField] protected float groundCheckDistance;
    [SerializeField] protected Transform groundCheck;
    [Space]
    [SerializeField] protected Transform wallCheck;
    [SerializeField] protected float wallCheckDistance;

    protected int facingDir = 1;
    protected bool facingRight = true;

    protected virtual void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponentInChildren<Animator>();
    }

    protected virtual void Update()
    {
        CheckCollision();
    }
    //检测是否撞墙或者离开地面
    protected virtual void CheckCollision()
    {
        isGrounded = Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);
        isWallDetected = Physics2D.Raycast(wallCheck.position, Vector2.right, wallCheckDistance * facingDir, whatIsGround);
    }
    //转向
    protected virtual void Flip()
    {
        facingDir *= -1;
        facingRight = !facingRight;
        transform.Rotate(0, 180, 0);
    }
    //画线 检测撞墙的线和检测离地的线
    protected virtual void OnDrawGizmos()
    {
        Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));
        Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance * facingDir, wallCheck.position.y));
    }
}


Player.cs

using UnityEngine;
//玩家类
public class Player : Entity
{
    [Header("Move Info")]
    [SerializeField] private float xInput;
    [SerializeField] private float moveSpeed = 4;
    [SerializeField] private float junpForce = 7;

    [Header("Dash Info")]
    [SerializeField] private float dashDuration;
    [SerializeField] private float dashTime;
    [SerializeField] private float dashSpeed;
    [SerializeField] private float dashCalmDuration;
    [SerializeField] private float dashCalmTime;

    [Header("Attack Info")]
    [SerializeField] private bool isAttacking;
    [SerializeField] private int comboCounter;
    [SerializeField] private float comboDuration;
    [SerializeField] private float comboTimeWindow;


    protected override void Start()
    {
        base.Start();
    }
    protected override void Update()
    {
        base.Update();
        FlipController();
        Movement();
        CheckInput();
        AnimatorController();

        Dash();
        Attack();
        comboTimeWindow -= Time.deltaTime;
    }
    //鼠标左键攻击
    private void Attack()
    {
        if (!isGrounded)
            return;
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            StartAttackEvent();
        }
    }
    //攻击事件
    private void StartAttackEvent()
    {
        if (comboTimeWindow < 0)
            comboCounter = 0;
        isAttacking = true;
        comboTimeWindow = comboDuration;
    }
    //攻击结束
    public void AttackOver()
    {
        isAttacking = false;
        comboCounter++;
        if (comboCounter > 2)
            comboCounter = 0;

    }
    //冲刺控制
    private void Dash()
    {
        dashTime -= Time.deltaTime;
        dashCalmTime -= Time.deltaTime;
        if (Input.GetKeyDown(KeyCode.LeftShift))
        {
            DashAbillity();
        }
    }
    //冲刺判定
    private void DashAbillity()
    {
        if (dashCalmTime < 0 && !isAttacking)
        {
            dashTime = dashDuration;
            dashCalmTime = dashCalmDuration;
        }
    }

    //检查输入

    private void CheckInput()
    {
        xInput = Input.GetAxisRaw("Horizontal");

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Jump();
        }
    }
    //移动控制
    private void Movement()
    {
        if (isAttacking)
        {
            rb.velocity = new Vector2(0, 0);
        }
        else if(dashTime > 0)
        {
            rb.velocity = new Vector2(facingDir * dashSpeed,0);

        }
        else
        {
            rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
        }
    }
    //跳跃控制
    private void Jump()
    {
        if(isGrounded)
            rb.velocity = new Vector2(rb.velocity.x, junpForce);
    }
    //动画播放控制
    private void AnimatorController()
    {
        bool isMoving = rb.velocity.x != 0;
        anim.SetBool("isMoving", isMoving);
        anim.SetBool("isGrounded", isGrounded);
        anim.SetFloat("yVelocity", rb.velocity.y);
        anim.SetBool("isDashing", dashTime > 0);
        anim.SetBool("isAttacking", isAttacking);
        anim.SetInteger("comboCounter", comboCounter);

    }


    //转向控制
    private void FlipController()
    {
        if(rb.velocity.x > 0 && !facingRight)
            Flip();
        else if(rb.velocity.x < 0 && facingRight)
            Flip();
    }



}


PlayerAnimEvents.cs

using UnityEngine;

public class PlayerAnimEvents : MonoBehaviour
{
    private Player player;
    private void Start()
    {
        player = GetComponentInParent<Player>();
    }
    private void AnimationTrigger()
    {
        player.AttackOver();
    }
}

### 使用C++开发银河恶魔城游戏的方法和资源 #### 选择合适的游戏引擎 为了简化开发过程并提高效率,推荐使用成熟的游戏引擎来构建银河恶魔城游戏。一些流行的选项包括Unreal Engine[^1] 和 Godot (尽管Godot主要支持GDScript, C#, 和Visual Scripting)[^2] 。然而,如果坚持使用纯C++进行开发,则可以选择像SFML 或 Allegro这样的轻量级跨平台图形库。 #### 学习基础概念和技术栈 掌握面向对象编程(OOP),这是C++的核心特性之一;理解内存管理机制以及指针操作等高级主题也是必不可少的。此外还需要学习有关窗口创建、事件处理循环、图像渲染等方面的知识。 #### 获取必要的工具链和支持材料 安装编译器(如GCC/MinGW)、IDE(集成开发环境)(例如 Visual Studio Code 或 CLion), 并配置好项目结构以便于管理和维护源文件。同时利用在线教程、官方文档和其他社区贡献者分享的经验教训作为指导资料。 ```cpp // 初始化游戏窗口示例代码片段 #include <SFML/Graphics.hpp> int main() { sf::RenderWindow window(sf::VideoMode(800, 600), "Metroidvania Game"); while (window.isOpen()) { // 处理输入... // 更新逻辑... // 渲染画面... window.clear(); // 绘制场景中的物体到屏幕上 window.display(); } return 0; } ``` #### 寻找灵感与参考案例研究 观察其他成功的同作品可以帮助形成自己的设计理念。分析《空洞骑士》或《奥日与黑暗森林》这经典之作是如何设计关卡布局、角色动作模式及其背后的技术实现方式能够提供宝贵启示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值