C++ 需要帮助优化C++;

C++ 需要帮助优化C++;,c++,optimization,collision-detection,game-physics,C++,Optimization,Collision Detection,Game Physics,我在GameBoyAdvance上编写了一个简单的自上而下的汽车驾驶游戏,类似于第一款GTA。我只使用了矢量图形,而GBA并不能很好地处理它;基本上有5个行人实例,它滞后 我在优化代码方面没有太多经验,所以我想知道我是否可以对代码进行一些调整,以使其运行更快,而不是依赖于它在GBA上运行的事实 我使用的碰撞测试是SAT(分离轴定理),因为我发现它是最容易使用矢量图形进行碰撞检查的测试;这个游戏本身很简单 代码如下: /* GTA Vector City Author: Alberto Taiut

我在GameBoyAdvance上编写了一个简单的自上而下的汽车驾驶游戏,类似于第一款GTA。我只使用了矢量图形,而GBA并不能很好地处理它;基本上有5个行人实例,它滞后

我在优化代码方面没有太多经验,所以我想知道我是否可以对代码进行一些调整,以使其运行更快,而不是依赖于它在GBA上运行的事实

我使用的碰撞测试是SAT(分离轴定理),因为我发现它是最容易使用矢量图形进行碰撞检查的测试;这个游戏本身很简单

代码如下:

/*
GTA Vector City
Author: Alberto Taiuti
Version: 2.0
*/

#include "Global.h"
#include <string.h>
#include <cstdio>
#include "font.h"
#include "CVector2D.h"
#include "CCar.h"
#include "CPed.h"
#include <vector>
#include <memory>

/* GLOBAL VARIABLES */
void CheckCollisionsRect(CRect *test_a, CRect *test_b);
std::vector<CVector2D> PrepVectors(CRect *shape);
CVector2D GetMinMaxShape(std::vector<CVector2D> vect_shape, CVector2D axis);
void CheckCollisionRectVSPoint(CRect *test_a, CVector2D *point);

/* MAIN */

// The entry point for the game
int main()
{
// Frame counter
uint32_t frames = 0;

// Previous & current buttons states
static uint16_t prev_buttons = 0, cur_buttons = 0;

  // Put the display into bitmap mode 3, and enable background 2.
REG_DISPCNT = MODE4 | BG2_ENABLE;

    // Set up the palette.
SetPaletteBG(BLACK, RGB(0, 0, 0)); // black
SetPaletteBG(WHITE, RGB(31, 31, 31)); // white
SetPaletteBG(GREY, RGB(15, 15, 15)); // grey
SetPaletteBG(RED, RGB(31, 0, 0)); // red
SetPaletteBG(GREEN, RGB(0, 31, 0)); // green
SetPaletteBG(BLUE, RGB(0, 0, 31)); // blue

// Create car instance
CCar *car = new CCar(50,50);

// Create a building
/*CRect *test_b = new CRect(100.0f, 100.0f, 30, 30);
CRect *test_c = new CRect(120.0f, 120.0f, 30, 30);
CRect *test_d = new CRect(30.0f, 30.0f, 30, 30);*/

// Pedestrian instances
int ped_number = 10; // Number of pedestrians
std::vector<CPed*> peds; // Ped. entities container (made of smart pointers)
typedef std::vector<CPed*>::iterator p_itor; // Iterator

for(int i = 1; i <= ped_number; i++)
{
    peds.push_back(new CPed(i, RED, 2.0f));
}

// Check whether the game is over
bool end = false;

// Main loop
while (!end)
{
    // Flip the screen
    FlipBuffers();

    //Clear the screen
    ClearScreen8(BLACK);

    // Update frame counter
    frames ++;  

    // Get the current state of the buttons.
    cur_buttons = REG_KEYINPUT;

    // Handle Input
    car->HandleInput(prev_buttons, cur_buttons);

    // Logic

    car->Update();
    for(int i = 0; i < ped_number; i++)
    {
        peds[i]->Update();
    }

    for(int i = 0; i < ped_number; i++)
    {
        CheckCollisionRectVSPoint(car->shape, peds[i]->pos);
    }

    /*CheckCollisionsRect(car->shape, test_b);
    CheckCollisionsRect(car->shape, test_c);
    CheckCollisionsRect(car->shape, test_d);
    CheckCollisionRectVSPoint(car->shape, test_ped->pos);*/

    // Render
    car->Draw();
    for(int i = 0; i < ped_number; i++)
    {
        peds[i]->Draw();
    }
    /*test_b->DrawFrame8(GREEN);
    test_c->DrawFrame8(WHITE);
    test_d->DrawFrame8(RED);
    test_ped->Draw();*/


    prev_buttons = cur_buttons;

    // VSync
    WaitVSync();
}



// Free memory
delete car;
//delete test_b; delete test_c; delete test_d;
//delete test_ped;
for(p_itor itor = peds.begin(); itor != peds.end(); itor ++)// Delete pedestrians 
{
     peds.erase(itor);
}

return 0;
}

void CheckCollisionsRect(CRect *test_a, CRect *test_b)
{
// If the two shapes are close enough, check for collision, otherways skip and save calculations to the CPU
//if((pow((test_a->points[0]->x - test_b->points[0]->x), 2) + pow((test_a->points[0]->y - test_b->points[0]->y), 2)) < 25.0f) 
{

    // Prepare the normals for both shapes
    std::vector<CVector2D> normals_a = test_a->GetNormalsAsArray();
    std::vector<CVector2D> normals_b = test_b->GetNormalsAsArray();

    // Create two containers for holding the various vectors used for collision check
    std::vector<CVector2D> vect_test_a = PrepVectors(test_a);
    std::vector<CVector2D> vect_test_b = PrepVectors(test_b);

    // Get the min and max vectors for each shape for each projection (needed for SAT)
    CVector2D result_P1 = GetMinMaxShape(vect_test_a, normals_a[1]); //
    CVector2D result_P2 = GetMinMaxShape(vect_test_b, normals_a[1]); //
    // If the two objects are not colliding
    if(result_P1.y < result_P2.x || result_P2.y < result_P1.x)
    {
        return;
    }
    CVector2D result_Q1 = GetMinMaxShape(vect_test_a, normals_a[0]); // First axis couple
    CVector2D result_Q2 = GetMinMaxShape(vect_test_b, normals_a[0]); // 
    if(result_Q1.y < result_Q2.x || result_Q2.y < result_Q1.x)
    {
        return;
    }
    CVector2D result_R1 = GetMinMaxShape(vect_test_a, normals_b[1]); //
    CVector2D result_R2 = GetMinMaxShape(vect_test_b, normals_b[1]); //
    if(result_R1.y < result_R2.x || result_R2.y < result_R1.x)
    {
        return;
    }
    CVector2D result_S1 = GetMinMaxShape(vect_test_a, normals_b[0]); // Second axis couple
    CVector2D result_S2 = GetMinMaxShape(vect_test_b, normals_b[0]); // 
    if(result_S1.y < result_S2.x || result_S2.y < result_S1.x)
    {
        return;
    }


    // Do something
    PlotPixel8(200, 10, WHITE);
    PlotPixel8(200, 11, WHITE);
    PlotPixel8(200, 12, WHITE);

}
}

// Check for collision between an OOBB and a point
void CheckCollisionRectVSPoint(CRect *test_a, CVector2D *point)
{
// Prepare the normals for the shape
std::vector<CVector2D> normals_a = test_a->GetNormalsAsArray();

// Create a container for holding the various vectors used for collision check
std::vector<CVector2D> vect_test_a = PrepVectors(test_a);

// Get projections for the OOBB (needed for SAT)
CVector2D result_P1 = GetMinMaxShape(vect_test_a, normals_a[1]); 
float result_point = point->DotProduct(normals_a[1]); 
// If the two objects are not colliding on this axis
if(result_P1.y < result_point || result_point < result_P1.x)
{
    return;

}
CVector2D result_Q1 = GetMinMaxShape(vect_test_a, normals_a[0]);
result_point = point->DotProduct(normals_a[0]);
// If the two objects are not colliding on this axis
if(result_Q1.y < result_point || result_point < result_Q1.x)
{
    return;

}

// Do something
PlotPixel8(200, 10, WHITE);
PlotPixel8(200, 11, WHITE);
PlotPixel8(200, 12, WHITE); 
}

// Returns a container with projection vectors for a given shape
std::vector<CVector2D> PrepVectors(CRect *shape)
{
std::vector<CVector2D> vect;

// Create vectors for projection and load them into the arrays
for( uint16_t i=0; i < 5; i++)
{       
    // Get global position of vectors and then add them to the array
    vect.push_back(shape->GetVectorGlobal(i));
}

return vect;
}

CVector2D GetMinMaxShape(std::vector<CVector2D> vect_shape, CVector2D axis)
{
// Set initial minimum and maximum for shape's projection vectors
float min_proj = vect_shape[1].DotProduct(axis);
float max_proj = vect_shape[1].DotProduct(axis);
// Calculate max and min projection vectors by iterating along all of the corners
for(uint16_t i = 2; i < vect_shape.size(); i ++)
{
    float current_proj = vect_shape[i].DotProduct(axis);
    // Select minimum projection on axis
    if(current_proj < min_proj) // If current projection is smaller than the minimum one
        min_proj = current_proj;
    // Select maximum projection on axis
    if(current_proj > max_proj) // If current projection is greater than the minimum one
        max_proj = current_proj;
}

return (CVector2D(min_proj, max_proj)); // Return a vector2D as it is a handy way for returning a couple of values
}
/*
矢量城市
作者:阿尔贝托·泰乌蒂
版本:2.0
*/
#包括“Global.h”
#包括
#包括
#包括“font.h”
#包括“cvectro2d.h”
#包括“CCar.h”
#包括“CPed.h”
#包括
#包括
/*全局变量*/
无效检查冲突报告(正确*测试a,正确*测试b);
标准::矢量预处理矢量(正确*形状);
CVector2D GetMinMaxShape(标准::矢量向量_形,CVector2D轴);
无效检查碰撞点(正确*测试点a,CVector2D*点);
/*主要*/
//游戏的切入点
int main()
{
//帧计数器
uint32_t帧=0;
//以前和当前按钮状态
静态uint16上一个按钮=0,当前按钮=0;
//将显示器置于位图模式3,并启用背景2。
REG_DISPCNT=模式4 | BG2_启用;
//设置调色板。
SetPaletteBG(黑色,RGB(0,0,0));//黑色
SetPaletteBG(白色,RGB(31,31,31));//白色
SetPaletteBG(灰色,RGB(15,15,15));//灰色
SetPaletteBG(红色,RGB(31,0,0));//红色
SetPaletteBG(绿色,RGB(0,31,0));//绿色
SetPaletteBG(蓝色,RGB(0,0,31));//蓝色
//创建汽车实例
综合资本分析及审查*car=新的综合资本分析及审查(50,50);
//创建一个建筑
/*正确*测试b=新的正确(100.0f、100.0f、30、30);
正确*测试c=新的正确(120.0f、120.0f、30、30);
正确*测试d=新的正确(30.0f,30.0f,30,30)*/
//行人实例
int ped_number=10;//行人数量
std::vector peds;//Ped.entities容器(由智能指针组成)
typedef std::vector::迭代器p_itor;//迭代器
用于(int i=1;i手动输入(上一个按钮、当前按钮);
//逻辑
汽车->更新();
对于(int i=0;iUpdate();
}
对于(int i=0;i形状,peds[i]->pos);
}
/*检查碰撞反应(汽车->形状,测试b);
检查碰撞反应(汽车->形状,测试c);
检查碰撞反应(汽车->形状,测试d);
检查碰撞点(车辆->形状,测试->位置)*/
//渲染
car->Draw();
对于(int i=0;iDraw();
}
/*测试b->DrawFrame8(绿色);
测试c->DrawFrame8(白色);
测试->牵引架8(红色);
测试->绘制()*/
上一个按钮=当前按钮;
//垂直同步
WaitVSync();
}
//空闲内存
删除汽车;
//删除测试b;删除测试c;删除测试d;
//删除测试用例;
for(p_itor itor=peds.begin();itor!=peds.end();itor++)//删除行人
{
peds.擦除(itor);
}
返回0;
}
无效检查冲突报告(正确*测试a,正确*测试b)
{
//如果两个形状足够接近,请检查碰撞,否则跳过并将计算保存到CPU
//如果((功率((测试a->点[0]->x-测试b->点[0]->x),2)+功率((测试a->点[0]->y-测试b->点[0]->y),2))<25.0f)
{
//准备两个形状的法线
std::vector normals_a=test_a->getnormalsasray();
std::vector normals_b=test_b->getnormalsasray();
//创建两个容器,用于保存用于碰撞检查的各种向量
std::vector vect_test_a=预向量(test_a);
std::vector vect_test_b=预向量(test_b);
//获取每个投影的每个形状的最小和最大向量(SAT所需)
CVectr2D结果_P1=GetMinMaxShape(向量测试_a,法线_a[1])//
CVectr2D结果_P2=GetMinMaxShape(向量测试_b,法线_a[1])//
//如果两个对象没有碰撞
如果(结果_P1.y<结果_P2.x | |结果_P2.y<结果_P1.x)
{
返回;
}
CVectr2D结果_Q1=GetMinMaxShape(向量测试_a,法线_a[0])//第一对轴
CVectr2D结果_Q2=GetMinMaxShape(向量测试_b,法线_a[0])//
如果(结果_Q1.y<结果_Q2.x |结果_Q2.y<结果_Q1.x)
{
返回;
}
CVectr2D结果_R1=GetMinMaxShape(向量测试_a,法线_b[1])//
CVectr2D结果_R2=GetMinMaxShape(向量测试_b,法线_b[1])//
如果(结果_R1.y<结果_R2.x | |结果_R2.y<结果_R1.x)
{
返回;
}
CVectr2D结果_S1=GetMinMaxShape(向量测试_a,法线_b[0])//第二轴耦合
CVectr2D结果_S2=GetMinMaxShape(向量测试_b,法线_b[0])//
如果(结果_S1.y<结果_S2.x |结果_S2.y<结果_S1.x)
{
返回;
}
//做点什么
PlotPixel8(200,10,白色);
PlotPixel8(200,11,白色);
PlotPixel8(200,12,白色);
}
}
//检查OOBB和点之间的碰撞
无效检查碰撞点(正确*测试点a,CVector2D*点)
{
//准备形状的法线
std::vector normals_a=test_a->getnormalsasray();
//创建一个容器,用于保存用于碰撞检查的各种向量
std::vector vect_test_a=预向量(test_a);
//获取OOBB的投影(SAT需要)
CVectr2D结果_P1=GetMinMaxShape(向量测试_a,法线_a[1]);
浮点结果\点=点->点积(法线\点[1]);
//如果两个对象在此轴上没有碰撞
如果(结果_P1.y<结果_点| |结果_点<结果_P1.x)
{
返回;
}
CVectr2D结果_Q1=GetMinMaxShape(向量测试_a,法线_a[0]);
结果_点=点->点积(法线_a[0]);
//如果两个对象在此轴上没有碰撞
if(结果_Q1.y<结果_点| |结果_点<结果_Q1.x)
{
返回;
}
//做点什么
PlotPixel8(200,10,白色);
PlotPixel8(200,11,白色);
PlotPixel8(200,12,白色);
}
//返回一个包含
for(int i = 0; i < ped_number; i++)
{
    CheckCollisionRectVSPoint(car->shape, peds[i]->pos);
}
// Prepare the normals for both shapes
std::vector<CVector2D> normals_a = test_a->GetNormalsAsArray();  

// Create two containers for holding the various vectors used for collision check
std::vector<CVector2D> vect_test_a = PrepVectors(test_a);