gpt4 book ai didi

c++ - 我如何使用 tinyxml 将 xml 属性转换为 C++ 类

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:57:22 25 4
gpt4 key购买 nike

嘿,我正在尝试通过读取 .xml 文件中的烟花来创建烟花表演,然后该文件将遍历并启动每个烟花。

我按照 dinomage 上的教程了解如何使用 tinyxml,我了解到我可以将属性存储到 char 指针中,但我不知道如何将它们转换为 GLfloats 以将它们存储在我的类变量中。

我确实尝试过使用 atof,但是当我运行程序时,我遇到了很多错误,我猜这是因为指针只存储了我传递给我的变量的地址。

谁能指出我哪里出了问题以及我该如何解决这个问题?

更新

我发现 tinyxml 与 vs2010 不兼容,但 tinyxml 2 兼容,所以我更改了我的代码,但仍然无法加载我的属性我添加了错误检查,它打印出 xml 已加载但随后它不会加载根

代码已更新

代码:Firework.h

#ifndef FIREWORK_H
#define FIREWORK_H
#include <cstdlib>
#include <GL\GL.h>
#include <string>



const GLint particles= 50;

class Firework

{

public:

GLint x[particles];
GLint y[particles];
GLint VelX[particles];
GLint VelY[particles];
GLint Xpos;
GLint Ypos;
GLint Xspeed;
GLint Yspeed;



unsigned char red;
unsigned char blue;
unsigned char green;
GLfloat alpha;
GLfloat redStart;
GLfloat blueStart;
GLfloat greenStart;
std::string hexColour;
std::string type;

GLint timeUntilLaunch;
GLint startTime;
GLint endTime;
GLint duration;
GLfloat particleSize;
GLboolean hasExploded;




GLboolean rocket, fountain;

static const GLfloat gravity;
static const GLfloat baseYSpeed;
static const GLfloat maxYSpeed;

Firework();

void initialise();
void move();
void explode();




};




#endif

烟花.ccp

#include "Firework.h"
#include "tinyxml2.h"
#include<time.h>
#include <string>
#include<iostream>
#include <vector>

using namespace std;

const GLfloat Firework::gravity = 0.05f;
const GLfloat Firework::baseYSpeed = -4.0f;
const GLfloat Firework::maxYSpeed = -4.0f;

//int QueryAttributeStatus = elem->FirstChildElement("begin")- >QueryFloatAttribute(attr,&timeUntillLaunch);





int convertFromHex(string hex)

{

int value = 0;



int a = 0;

int b = hex.length() - 1;

for (; b >= 0; a++, b--)

{

if (hex[b] >= '0' && hex[b] <= '9')

{

value += (hex[b] - '0') * (1 << (a * 4));

}

else

{

switch (hex[b])

{

case 'A':

case 'a':

value += 10 * (1 << (a * 4));

break;



case 'B':

case 'b':

value += 11 * (1 << (a * 4));

break;



case 'C':

case 'c':

value += 12 * (1 << (a * 4));

break;



case 'D':

case 'd':

value += 13 * (1 << (a * 4));

break;



case 'E':

case 'e':

value += 14 * (1 << (a * 4));

break;



case 'F':

case 'f':

value += 15 * (1 << (a * 4));

break;



default:

cout << "Error, invalid charactare '" << hex[a] << "' in hex number" << endl;

break;

}

}

}
return value;

}


void hextodec(string hex, vector<unsigned char>& rgb)

{

/*
since there is no prefix attached to hex, use this code

string redString = hex.substr(0, 2);

string greenString = hex.substr(2, 2);

string blueString = hex.substr(4, 2);
*/



/*

if the prefix # was attached to hex, use the following code

string redString = hex.substr(1, 2);

string greenString = hex.substr(3, 2);

string blueString = hex.substr(5, 2);

*/





//if the prefix 0x was attached to hex, use the following code

string redString = hex.substr(2, 2);

string greenString = hex.substr(4, 2);

string blueString = hex.substr(6, 2);





unsigned char red = (unsigned char)(convertFromHex(redString));

unsigned char green = (unsigned char)(convertFromHex(greenString));

unsigned char blue = (unsigned char)(convertFromHex(blueString));



rgb[0] = red;

rgb[1] = green;

rgb[2] = blue;

}


Firework::Firework()
{

initialise();

}



void Firework::initialise()
{
tinyxml2::XMLDocument doc;
doc.LoadFile( "fireworks.xml");
if (!doc.LoadFile("fireworks.xml"))
{
std::cout<<"Failed to load file: no xml"<<endl;
}

else
std::cout<<"loaded xml"<<endl;



tinyxml2::XMLElement * root = doc.FirstChildElement();
if (root == NULL)
{
std::cout<<"Failed to load file: no root element."<<endl;

}

else

std::cout<<"root node loaded"<<endl;

for (tinyxml2::XMLElement* elem = root ->FirstChildElement(); elem!=NULL; elem = elem->NextSiblingElement())
{
string elemName = elem->Value();
const char* attr;

if (elemName == "Firework")
{
attr = elem->Attribute("begin");
if(attr != NULL)
{
elem->QueryIntAttribute("begin",&startTime);
}

attr = elem->Attribute("type");
if (attr != NULL)
{
type = elem->GetText();
if (type != "")

std::cout<<"have something"<<endl;


}

attr = elem ->Attribute("colour");
if (attr !=NULL)
{
hexColour= elem->GetText();
vector<unsigned char> rgbColor(3);

hextodec(hexColour,rgbColor);

red =int(rgbColor[0]);
blue = int(rgbColor[1]);
green= int(rgbColor[2]);


}

attr = elem->Attribute("duration");
if (attr !=NULL)
{
elem->QueryIntAttribute("duration", &endTime);
}

for (tinyxml2::XMLElement * e =elem ->FirstChildElement("Position"); e != NULL; e = e->NextSiblingElement("Position"))
{
attr = e->Attribute("x");
if (attr != NULL)
{
Xpos = e->QueryIntAttribute("x", &Xpos);
}

attr = e->Attribute("y");
if (attr != NULL)
{
Ypos = e->QueryIntAttribute("y", &Ypos);
}
}

for(tinyxml2::XMLElement * v =elem ->FirstChildElement("Velocity"); v !=NULL; v = v->NextSiblingElement("Velocity"))
{
attr = v -> Attribute("x");
if (attr != NULL)
{
Xspeed = v ->QueryIntAttribute("x", &Xspeed);
}

attr = v ->Attribute ("y");
if (attr !=NULL)
{
Yspeed = v ->QueryIntAttribute("y", &Yspeed);
}
}
}

}









//Setting initial x/y locations and speeds for each particle
for (int loop = 0; loop < particles; loop++)
{
x[loop] = Xpos;
y[loop] = Ypos;
VelX[loop] = Xspeed;
VelY[loop] = Yspeed;
}

//intiallising the colour and full alpha
redStart = 0.85f;//((float)rand() / (float)RAND_MAX);
greenStart = 0.55f;//((float)rand() / (float)RAND_MAX);
blueStart = 0.01f;//((float)rand() / (float)RAND_MAX);

alpha = 1.0f;

timeUntilLaunch = startTime;
duration = endTime;
particleSize = 1.0f + ((float)rand()/(float)RAND_MAX)* 3.0f;

hasExploded = false;
}

void Firework::move()
{
for (int loop = 0; loop < particles; loop++)
{
if (timeUntilLaunch <= 0)
{
x[loop] += VelX [loop];
y[loop] += VelY [loop];
VelY[loop] += Firework::gravity;
duration --;
}

}
timeUntilLaunch --;

if (duration <= 0)
{
for (int loop2 = 0; loop2 < particles; loop2++)
{
VelX[loop2] = -4 + (rand() / (int)RAND_MAX)*8;
VelY[loop2] = -4 + (rand() / (int)RAND_MAX)*8;
}
hasExploded = true;
}
}


void Firework::explode()
{
for (int loop = 0; loop < particles; loop++)
{
// Dampen the horizontal speed by 1% per frame
VelX[loop] *= 0.99f;

// Move the particle
x[loop] += VelX[loop];
y[loop] += VelY[loop];

// Apply gravity to the particle's speed
VelY[loop] += Firework::gravity;
}

// Fade out the particles (alpha is stored per firework, not per particle)
if (alpha > 0.0f)
{
alpha -= 0.01f;
}
else // Once the alpha hits zero, then reset the firework
{
initialise();
}
}

主.ccp

#include <iostream>
#include <ctime>
#include <time.h>
#include <windows.h> // *** IMPORTANT: Uncomment for Win32 systems - This must come -BEFORE- gl.h in the include list! ***
#include "GL\glfw.h"
#include "Firework.h"
#include <GL\GL.h>
#include <GL/glu.h>
#include "tinyxml2.h"


#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "lib/glfw/GLFW.lib")

using namespace std;


GLint windowWidth = 1024;
GLint windowHeight = 600;
GLint frameCount =0;
GLint texture;

const int FIREWORKS = 15; // Number of fireworks

Firework fw[FIREWORKS];


void initGL()

{
glfwSwapInterval(1);


glfwSetWindowTitle("Fireworks");

glViewport(0, 0, (GLsizei)windowWidth, (GLsizei)windowHeight);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0, windowWidth, windowHeight, 0, 0, 1);

glShadeModel(GL_SMOOTH);

// Set our clear colour to opaque black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

// Disable depth testing (because we're working in 2D!)
glDisable(GL_DEPTH_TEST);

// Enable blending (we need this to be able to use an alpha component)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Set the accumulation buffer clearing colour to opaque black
glClearAccum(0.0f, 0.0f, 0.0f, 1.0f);

glEnable(GL_POINT_SMOOTH);

}

void drawScene()

{
// Take the contents of the current accumulation buffer and copy it to the colour buffer so that it entirely overwrites it
glAccum(GL_RETURN, 1.0f);

// Clear the accumulation buffer (don't worry, we re-grab the screen into the accumulation buffer after drawing our current frame!)
glClear(GL_ACCUM_BUFFER_BIT);

// Set ModelView matrix mode and reset to the default identity matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Displacement trick for exact pixelisation
glTranslatef(0.375, 0.375, 0);

// Draw our fireworks
for (int loop = 0; loop < FIREWORKS; loop++)
{
for (int particleLoop = 0; particleLoop < particles; particleLoop++)
{

// Set the point size of the firework particles (this needs to be called BEFORE opening the glBegin(GL_POINTS) section!)
glPointSize(fw[loop].particleSize);

glBegin(GL_POINTS);
// Set colour to yellow on the way up, then whatever colour firework should be when exploded

if (fw[loop].hasExploded == false)
{
glColor4f(fw[loop].redStart, fw[loop].greenStart, fw[loop].blueStart, 1.0f);
}
else
{
glColor4f(fw[loop].red, fw[loop].green, fw[loop].blue, fw[loop].alpha);
}

// Draw the point
glVertex2f(fw[loop].x[particleLoop], fw[loop].y[particleLoop]);
glEnd();
}

// Move the firework appropriately depending on its explosion state
if (fw[loop].hasExploded == false && fw[loop].type=="Rocket")
{
fw[loop].move();
}
else
{
fw[loop].explode();
}

}

glAccum(GL_ACCUM, 0.85f);

glfwSwapBuffers();

}


int main()
{
int srand((unsigned)time(NULL)); // Seed the random number generator

// Define our buffer settings
int redBits = 8, greenBits = 8, blueBits = 8;
int alphaBits = 64, depthBits = 24, stencilBits = 8;

// Flag to keep our main loop running
bool running = true;

// Initialise glfw
glfwInit();

// Create a window
if(!glfwOpenWindow(windowWidth, windowHeight, redBits, greenBits, blueBits, alphaBits, 0, 0, GLFW_WINDOW))
{
cout << "Failed to open window!" << endl;
glfwTerminate();
return 0;
}

// Call our initGL function to set up our OpenGL options
initGL();

while (running == true)
{
// Draw our scene
drawScene();

// Increase our frame counter
frameCount++;

// Exit if ESC was pressed or the window was closed
running = glfwGetWindowParam(GLFW_OPENED);
}

glfwTerminate();

return 0;
}

烟花.xml

   <?xml version="1.0" ?>
<FireworkDisplay>
<Firework begin="1000" type="Fountain" colour="0x20FF40" duration="5000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="2000" type="Fountain" colour="0x4020FF" duration="4000">
<Position x="100" y="-384"/>
</Firework>
<Firework begin="3000" type="Fountain" colour="0xff5099" duration="3000">
<Position x="-100" y="-384"/>
</Firework>

<Firework begin="1000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="500" y="-384"/>
<Velocity x="-3" y="10"/>
</Firework>
<Firework begin="2000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="0" y="-384"/>
<Velocity x="0" y="10"/>
</Firework>
<Firework begin="3000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="-500" y="-384"/>
<Velocity x="3" y="10"/>
</Firework>

<Firework begin="11000" type="Rocket" colour="0xFFFF20" duration="1000">
<Position x="500" y="-384"/>
<Velocity x="-3" y="10"/>
</Firework>
<Firework begin="12000" type="Rocket" colour="0xFF2020" duration="1000">
<Position x="0" y="-384"/>
<Velocity x="0" y="10"/>
</Firework>
<Firework begin="13000" type="Rocket" colour="0xFF20FF" duration="1000">
<Position x="-500" y="-384"/>
<Velocity x="3" y="10"/>
</Firework>


<Firework begin="4000" type="Fountain" colour="0xffFF40" duration="5000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="5000" type="Fountain" colour="0x4020FF" duration="4000">
<Position x="-200" y="-384"/>
</Firework>
<Firework begin="6000" type="Fountain" colour="0xff5099" duration="3000">
<Position x="200" y="-384"/>
</Firework>

<Firework begin="7000" type="Fountain" colour="0x20FF40" duration="5000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="8000" type="Fountain" colour="0x4020FF" duration="4000">
<Position x="400" y="-384"/>
</Firework>
<Firework begin="9000" type="Fountain" colour="0xff5099" duration="3000">
<Position x="-400" y="-384"/>
</Firework>


<Firework begin="10000" type="Fountain" colour="0xff8040" duration="1000">
<Position x="-450" y="-384"/>
</Firework>
<Firework begin="10500" type="Fountain" colour="0x40ffFF" duration="1000">
<Position x="-220" y="-384"/>
</Firework>
<Firework begin="11000" type="Fountain" colour="0xffff99" duration="1000">
<Position x="0" y="-384"/>
</Firework>
<Firework begin="11500" type="Fountain" colour="0xff00ff" duration="1000">
<Position x="220" y="-384"/>
</Firework>
<Firework begin="12000" type="Fountain" colour="0x40ffFF" duration="1000">
<Position x="450" y="-384"/>
</Firework>

</FireworkDisplay>

最佳答案

if (attr == "Fountain")

这是错误的。它比较指针,而不是字符串内容。使用 strcmp。检查每次出现的情况。

if ( rocket = true)

这将始终为真,因为它是一个赋值,请使用 == 代替。检查每次出现的情况。

关于c++ - 我如何使用 tinyxml 将 xml 属性转换为 C++ 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16426381/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com