07c++呵呵老师【FPS实现射击】

将发射物添加到游戏

添加射击操作映射

1.点击 项目设置(Project Settings)

 2.点击 输入(Input)

3.点击 操作映射(Action Mappings) 旁边的+号

4.在显示的文本输入框中输入"Fire"

5.从 鼠标(Mouse) 下拉列表中选择 鼠标左键(Left Mouse Button)

添加发射物类

1.在文件(File)菜单中,选择 新建C++类...(New C++ Class...),以选择新的父类

2.选择 Actor 作为父类,然后点击 下一步(Next)

 3.将新类命名为"FPSProjectile",然后点击 创建类(Create Class)

================================================

给发射物添加球体碰撞组件

1.打开 FPSProjectile.h

2.添加SphereComponent头文件

#include "Components/SphereComponent.h"

 3.添加 USphereComponent 的引用变量

// 球体碰撞组件。
UPROPERTY(VisibleDefaultsOnly, Category = Projectile)
USphereComponent* CollisionComponent;

4.在 AFPSProjectile 构造函数中进行初始化

if(!RootComponent)
{
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("ProjectileSceneComponent"));
}
if(!CollisionComponent)
{
// 用球体进行简单的碰撞展示。
CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
// 设置球体的碰撞半径。
CollisionComponent->InitSphereRadius(15.0f);
// 将根组件设置为碰撞组件。
RootComponent = CollisionComponent;
}

===================================================

添加发射物移动组件

1.打开 FPSProjectile.h

2.添加ProjectileMovementComponent头文件。

#include "GameFramework/ProjectileMovementComponent.h"

3.添加组件变量

// 发射物移动组件。
UPROPERTY(VisibleAnywhere, Category = Movement)
UProjectileMovementComponent* ProjectileMovementComponent;

4.在构造函数中进行初始化

if(!ProjectileMovementComponent)
{
    // 使用此组件驱动发射物的移动。
    ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
    //更新组件(参数)的位置,通常是更新actor根组件的位置
    ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
    //发射物初始速度
    ProjectileMovementComponent->InitialSpeed = 3000.0f;
    //发射物最高速度
    ProjectileMovementComponent->MaxSpeed = 3000.0f;
    //发射物的选择在每一帧进行更新
    ProjectileMovementComponent->bRotationFollowsVelocity = true;
    //设置反弹
    ProjectileMovementComponent->bShouldBounce = true;
    //反弹系数
    ProjectileMovementComponent->Bounciness = 0.3f;
    //发射物重量
    ProjectileMovementComponent->ProjectileGravityScale = 0.0f;
}

===========================================

设置发射物的速度

1.在FPSProjectile.h中添加以下函数声明

// 初始化射击方向上发射物速度的函数。
void FireInDirection(const FVector& ShootDirection);

2.将以下函数定义添加到 FPSProjectile.cpp

// 初始化射击方向上发射物速度的函数。
void AFPSProjectile::FireInDirection(const FVector& ShootDirection)
{
    ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}

 ======================================

绑定发射输入操作

1.在 FPSCharacter.h 中添加以下函数声明

// 处理发射物射击的函数。
UFUNCTION()
void Fire();

2.要绑定发射函数,请将以下代码添加到 FPSCharacter.cpp 中的 SetupPlayerInputComponent 函数中:

PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire);

 3.现在,将以下函数定义添加到 FPSCharacter.cpp

void AFPSCharacter::Fire()
{
}

==========================================

定义发射物的生成位置 

生成 FPSProjectile actor并实现 OnFire 函数时需要考虑两点,即:

(1)发射物的生成位置

(2)发射物对应的类(让 FPSCharacter 及其派生蓝图知道要生成哪种发射物)

1.首先确定,枪口与摄像机的相对偏移位置变量

// 枪口相对于摄像机位置的偏移。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
FVector MuzzleOffset;

2.添加发射物类型的变量,注意这是 protect类型的

// 要生成的发射物类。
UPROPERTY(EditDefaultsOnly, Category = Projectile)
TSubclassOf<class AFPSProjectile> ProjectileClass;

===============================================

实现射击

1.在FPSCharacter.h中引入发射物的头文件

#include "FPSProjectile.h"

2.定义cpp中的发射函数

void AFPSCharacter::Fire()
{
// 试图发射发射物。
if (ProjectileClass)
{
// 获取摄像机变换。
FVector CameraLocation;
FRotator CameraRotation;
GetActorEyesViewPoint(CameraLocation, CameraRotation);

// 设置MuzzleOffset,在略靠近摄像机前生成发射物。
MuzzleOffset.Set(100.0f, 0.0f, 0.0f);

// 将MuzzleOffset从摄像机空间变换到世界空间。
FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);

// 使目标方向略向上倾斜。
FRotator MuzzleRotation = CameraRotation;
MuzzleRotation.Pitch += 10.0f;

UWorld* World = GetWorld();
if (World)
{
    FActorSpawnParameters SpawnParams;
    SpawnParams.Owner = this;
    SpawnParams.Instigator = GetInstigator();

    // 在枪口位置生成发射物。
    AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
    if (Projectile)
    {
        // 设置发射物的初始轨迹。
        FVector LaunchDirection = MuzzleRotation.Vector();
        Projectile->FireInDirection(LaunchDirection);
    }
}
}
}

 ============================================

添加发射物网格体

1.在FPSProjectile.h添加头文件

#include "Components/StaticMeshComponent.h"

2.在FPSProjectile.h添加网格体变量

// 发射物网格体
UPROPERTY(BlueprintReadWrite , Category = Projectile)
UStaticMeshComponent* ProjectileMeshComponent;

3.在构造函数中初始化

if (!ProjectileMeshComponent)
	{
		ProjectileMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ProjectileMeshComponent"));
		static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/Food_Pack_01/Meshes/Food_Fruit_Lime_01.Food_Fruit_Lime_01"));
	

		if (CubeVisualAsset.Succeeded())
		{
			ProjectileMeshComponent->SetStaticMesh(CubeVisualAsset.Object);
			
			ProjectileMeshComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
		}
	}

====================

进入蓝图文件夹,并打开BP_FPSCharacter文件

选择我们的抛射物类

测试,发射发射物时,会在世界大纲视图中看到发射物的数量不断增加,因为它们没有已定义的生命周期。 

============================================

 设置发射物的碰撞和生命周期

1.将以下代码添加到FPSProjectile构造函数中,以设置发射物的生命周期:

// 3 秒后删除发射物。
InitialLifeSpan = 3.0f;

2.测试,可以自定删除

编辑发射物的碰撞设置

1.要创建自定义碰撞通道,打开项目设置(Project Settings),在引擎(Engine) - 碰撞(Collision)中,展开预设(Preset)

 2.在对象通道(Object Channels)中,选择 新建对象通道...(New Object Channel...),创建新碰撞通道。将新碰撞通道命名为"Projectile",确保将默认响应(Default Response)设置为阻止(Block),然后点击接受(Accept)。

  

3. 在预设(Preset)中选择 新建...(New...),将新配置文件命名为"Projectile"。参考以下图片来设置你的碰撞预设。然后点击"接受(Accept)"。

 

使用新碰撞通道的设置

1.在FPSProjectile构造函数中,将以下代码行添加到CreateDefaultSubobject下方 

// 将球体的碰撞配置文件名称设置为"Projectile"。
CollisionComponent->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));

 射击有点小问题,但是大部分问题已经解决。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
用DDraw实现射击游戏说明文档 要点一:画图自动切割 IDirectDrawSurface7::BltFast()方法中没有自动切割功能,即当画图元素超出窗口以外时不会自动切割,DDraw选择自动忽略不画,造成一旦超出窗口,画图元素会突然消失。 解决这一问题的方法是手动切割,代码如下: //自动切割 RECT scRect; //存放当前窗口大小区域 ZeroMemory( &scRect, sizeof( scRect ) ); GetWindowRect( GetActiveWindow(), &scRect ); //防止图片左上角超过窗口左上角 if ( x < 0 ) { m_rect.left -= x; x = 0; } if ( y scRect.right ? scRect.right : x; y = y > scRect.bottom ? scRect.bottom : y; m_rect.right = x + m_rect.right - m_rect.left > scRect.right ? scRect.right - x + m_rect.left : m_rect.right; m_rect.bottom = y + m_rect.bottom - m_rect.top > scRect.bottom ? scRect.bottom - y + m_rect.top : m_rect.bottom; 只需将上述代码加在CGraphic::BltBBuffer() 中的m_bRect = m_rect; 前即可。 要点二:背景的滚轴实现 画背景可以分为以下三种情况: 情况一:背景图片与窗口等高 情况二:背景图片高度小于窗口高度 情况三:背景图片高度大于窗口高度 上述讲解图与代码相对应地看,有助于容易理解。 另外,要点一实现之后,由于已经可以自动切割,画背景可以用其它方法。 要点三:精灵图的实现游戏中,如RPG游戏中的人物图、射击游戏的飞机、爆炸等,叫做精灵图。 精灵图实际上是将所有帧的图片放在一个文件中,游戏时靠一个RECT来控制画图像文件中的哪一部分,进而控制游戏显示哪一帧图,只需控制好RECT的位置即可。如下图: 控制RECT的四个角的坐标的移动,有以下代码: if (m_timeEnd – m_timeStart > 100) //只有到了100ms之后才绘图 { m_ImageID++; if(m_ImageID - m_beginID >= num) { m_ImageID = m_beginID; //最后一帧的下一帧是第一帧 } m_timeStart = timeGetTime(); } int id = m_ImageID++; SetRect(&m_rect, 41 * id, 0, 41 * (id + 1), 41); //飞机精灵图大小是41×41 m_pGraph->BltBBuffer(m_pImageBuffer, true, m_Pos.x, m_Pos.y, m_rect); 这样就实现了精灵动画的效果。 要点四:拿STL进行子弹的实现 子弹的实现可以使用STL中的vector,当按下开火键时发出一颗子弹,就往vector中添加一个结点;当子弹飞出窗口或击中敌机时,再将结点从vector中删除。每帧游戏画面中子弹飞行时只需将vector中的所有子弹进行处理、绘画即可。 参考代码如下: 1.添加子弹 if (g_ctrlDown) //当ctrl键按下时开炮! { m_BulletEnd = m_Gtime->GetTime(); if ((m_BulletEnd - m_BulletStart) * 1000 > 120) //如果连续按着开火键不放,这里控制不会发出太多子弹 { m_BulletStart = m_BulletEnd; MBULLET tmpBullet; tmpBullet.pos.x = m_SPos.x - 1; //记录开火时的子弹位置 tmpBullet.pos.y = m_SPos.y - 26; tmpBullet.speed = 5; //该子弹的飞行速度 m_BulletList.push_back(tmpBullet); //将子弹添加到vector中
使用的 主要技术有: 1、大面积山脉渲染,使用Heightmap构造地形,7级 LOD 细节精度,地形无限重复循环 。 2、清晰、自然的地表贴图。 3、读取.MD2 、.MS3D 格式的3D模型文件。 4、粒子系统,产生爆炸、炊烟等特效。 5、太阳光晕。 6、使用Blend模拟Brightness/contrast调节图象亮度。 操作控制 可以在GameSetting菜单中设定: 1.视频属性 ( Video Setting ) 1).屏幕分辨率( Resolution ) 游戏率默认为800*600,在任务执行前可改变分辨率,但不会立即生效,只有在初始化任务时才改变分辨率。 2).屏幕亮度( Brigthness ) 在不同的硬件配置上,屏幕亮度往往表现出较大差异,通过该项可将亮度调节到最佳。 3).视野范围 ( Visible Distance ) 调节地形绘制的距离。对于配置较低的硬件,适当降低视野距离可提高帧速率,但由于远处地形网格较粗,对帧速率提高贡献并不大。 4).雾浓度 ( Fog Density ) 2.音频属性 ( Audio Setting ) 1).背景音乐(music) 可以打开或关闭背景音乐,可以调节音量。 音乐播放 audio/music/menu.mp3 ,如果你有自己喜爱的mp3音乐文件可以将它替换 menu.mp3 文件。 2).音效( sound ) 可以打开或关闭音效,可以调节音量。游戏中的枪声与人物的发声具有3D效果。 3.键盘操作 ( Keyboard Setting ) 以下操作可以更改 Up、Down、Left、Right设定移动操作。 Fire 射击 Jump 跳跃 Zoom 放大远处景物 Help 弹出帮助 修改方法:用鼠标点击选项,然后输入新的按键。 另外,游戏保留了几个开发模式下的操作: Page Up 提升视点高度 Page Down 降低视点高度 (可以看到地形绘制区域) L 线框模式 F 冻结所有敌人 V 隐身 N 敌人攻击力为零 I 隐藏房子 O 隐藏敌人 P 隐藏树木 在游戏运行中,按 Help 项的按键获得帮助。 4.鼠标操作 鼠标的移动可改变视角,默认设定左键为射击,右键为放大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无情的阅读机器

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值