• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

buggypixels

Members
  • Content count

    13
  • Joined

  • Last visited

Community Reputation

371 Neutral

About buggypixels

  • Rank
    Member
  1. It is interesting to see that most frameworks will force you to use a pattern that you should clearly avoid. We all have learned that having something like GameObjects and call an update method in every object is bad due to cache misses and so on. This is the gap that actually ECS tries to eliminate. So in general it is bad practice to do it like Cocos2d. On the other hand how would you do it when you are such a framework designer? This is the only currently somehow accepted solution. Since there still is no common vision how a ECS should be designed and there are many different solutions out there it is safe to fall back to such an approach. But still it is bad design.
  2. The basic idea of supporting events in a game engine is nice. Actually it is a simple way of decoupling different systems. Somehow it seems that providing a gobal event manager is a common approach.  I strongly disagree here and here is a perfect explanation why: http://bitsquid.blogspot.de/2009/12/events.html I really like the idea and in my games all that is left of my previous event system is just an event stream buffer. Now a subsystem can write to its own event buffer stream and a higher level system may ask for the stream and process it. IMHO it makes everything so much easier and predictable.
  3. I have recently reworked by event system completely and it now looks totally different. First of all I did the same design flaw that you can find in many solutions. There is something like [code] void fireEvent(EventData* evn) { foreach ( Listener l : listeners ) { onEvent(evn); } } [/code] First using a raw pointer here is awfull. But the major problem is that every event will be processed immediately when they are fired. This leads to unpredictable circumstances in your code. You actually never know WHEN an event will be fired and therefore you cannot know the states of your objects. So what I did was to buffer the events and then at a certain point in my engine (right after the big update loop) I process ALL events and send them to the listeners. Also in my opinion using a base class for an event is awfull. An event contains only data. You are just sending plain data around. So I removed this completely and just using structs. This makes the code much leaner and cleaner. The entire solution now looks completely different. I got the idea after reading this: [url="http://bitsquid.blogspot.com/2011/02/managing-decoupling-part-2-polling.html"]http://bitsquid.blogspot.com/2011/02/managing-decoupling-part-2-polling.html[/url] It took me quite a while to finally get it and then it just hit me how awfully right the author is. Actually I now have a buffer where I store the events like: [header1][event data][header2][event data2] The header is a simple struct: [code] struct Header { uint32 index; uint32 id; size_t size; }; [/code] The ID is the actual ID of the event and the size is the size of the event data struct. The index is the actual index in my buffer. The entire buffer is sent to any listener and the listener can grab any data he likes from the buffer like: [code] size_t get(void* p, size_t size,uint32 index); [/code] Example: Here is the event data when the ship is hit by a projectile: [code] struct ShipHit { Vec2 pos; int damage; int rocketType; } [/code] Now I fire the event: [code] ShipHit sh; sh.pos = Vec2(100,100); sh.rocketType = 1; sh.damage = 100; evnetManager->fireEvent(100,&sh,sizeof(sh); [/code] In the listener I do something like: [code] // check if we have a ship hit event in the buffer if ( buffer.containsID(100) ) { // yes so grab the data ShipHit sh; buffer.get(100,&sh,sizeof(sh)); } [/code] I hope I could actually shed some light on my approach. It is actually not easy and I am not sure I could get the point across. Just ask if you have any questions.
  4. You might take a look here: [url="http://gamesfromwithin.com/managing-data-relationships"]http://gamesfromwithin.com/managing-data-relationships[/url]. Since your example is about resource management this might fit perfectly. Overall using strings and std::map is not the best solution here. If you still need to support strings (better to say to support name lookups) you can easily extend the system described above to include a name/handler mapping.
  5. [quote name='unbird' timestamp='1295436574' post='4761192'] I've one concern with your implementation, though: You're fixed to 16-bit indices. I'm not very much C++, but you could probably just use a second type parameter for your template [/quote] You are right. Right now I only need 16-bit indices in my engine. But it should be straight forward to use the index type as second template type. My next step is to support subsets within the vertex buffer. Basically the same as you have when using the IDXMesh object. So I can activate or deactivate certain subsets and do not take care of rendering any particular subset individually. Someone might argue that I could use the said IDXMesh. But hey, I am doing it for the fun of it. As you can see that actual part of setting textures/shaders/materials are not part of the vertex buffer since the engine during the render stages takes care of this already. So probably this is not as generic as it could be. I just wanted to share the idea of using a template here.
  6. I have posted the code along with some short explanations at my webset [url="http://www.buggypixels.com"]buggypixels.com[/url] Hope you find it interesting.
  7. The solution was quite easy. Instead of using vector I am not using an array. It is also much easier to copy the data to memory. Now I have a nice vertex and index buffer that can use any kind of vertex data. If anyone is interested I can post the code.
  8. Hi everyone, I am trying to build a generic vertexbuffer. Generic means that I could use any kind of Vertex along a VertexDeclaration. So far I have a working version which is posted below. The problem is the way how I copy the data to the vertex buffer. First I get a warning from the compiler. Here is the snippet: [code] template<class T> void DynamicVertexBuffer<T>::update() { int total = m_Vertices.size(); if ( total > 0 ) { T* pVertices; HR(vertexBuffer->Lock( 0, 0, ( void** )&pVertices, 0 )); for ( size_t i = 0; i < total; ++i ) { m_Vertices[i]->set(pVertices); pVertices++; } HR(vertexBuffer->Unlock()); } m_numVertices = total; }[/code] Basically I want the vertex buffer to have a list/vector of vertices and the update method will copy the vertices to the buffer. The warning is about this line: [code] T* pVertices; [/code] Also I do not like the way how I currently handle the building of the pointer: [code] m_Vertices[i]->set(pVertices); [/code] But that was the only solution I could come up with that is working. When you search around the internet you can find a huge list of examples but they all take a slightly different approach. For example Chad Vernon uses a method like this in his generic vertex buffer: [code] BOOL SetData( UINT numVertices, void *pVertices, DWORD flags = D3DLOCK_DISCARD ); [/code] So in his code the vertex buffer is not storing the data (which I would prefer). Also he uses arrays and memcopy to build the actual vertex buffer. I would still prefer the vector/list approach. Now here are my questions: [list][*]I am on the wrong track[*]Can somebody give me a hint about the compiler warning[*]Does someone has a better idea[*]Should I drop my stuff and simply take the same approach as all the others[/list] Any feedback would be great. Here is the entire code: [code] #pragma once #include "..\dxstdafx.h" #include "IndexBuffer.h" #include <vector> namespace ds { template <class T> class DynamicVertexBuffer { typedef std::vector<T*> Vertices; public: DynamicVertexBuffer(D3DPRIMITIVETYPE primitiveType,IDirect3DVertexDeclaration9* vertexDeclaration,const int& vertexSize,const int& maxVertices); ~DynamicVertexBuffer(); void addVertex(T* v); void clear(); void update(); void preRendering(); void render(int numPrimitives); void postRendering(); private: Vertices m_Vertices; int m_MaxVertices; IDirect3DVertexDeclaration9* m_VertexDeclaration; LPDIRECT3DVERTEXBUFFER9 vertexBuffer; IndexBuffer* indexBuffer; UINT m_numVertices; int m_vertexSize; D3DPRIMITIVETYPE m_primitiveType; }; template<class T> DynamicVertexBuffer<T>::DynamicVertexBuffer(D3DPRIMITIVETYPE primitiveType,IDirect3DVertexDeclaration9* vertexDeclaration,const int& vertexSize,const int& maxVertices) : m_VertexDeclaration(vertexDeclaration) , m_vertexSize(vertexSize) , m_primitiveType(primitiveType) , m_MaxVertices(maxVertices) { IDirect3DDevice9 * pDevice = gEngine->getDevice(); D3DPOOL pool = D3DPOOL_DEFAULT; DWORD usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC; LOG(logINFO) << "creating new dynamic vertext buffer - size: " << m_MaxVertices; HR(pDevice->CreateVertexBuffer( m_MaxVertices * vertexSize,usage,0 ,pool, &vertexBuffer, NULL )); indexBuffer = 0; } template<class T> DynamicVertexBuffer<T>::~DynamicVertexBuffer() { if( vertexBuffer ) { vertexBuffer->Release(); vertexBuffer = NULL; } } template<class T> void DynamicVertexBuffer<T>::addVertex(T* v) { m_Vertices.push_back(v); } template<class T> void DynamicVertexBuffer<T>::clear() { for ( size_t i = 0 ; i < m_Vertices.size(); ++i ) { delete m_Vertices[i]; } m_Vertices.clear(); } template<class T> void DynamicVertexBuffer<T>::update() { int total = m_Vertices.size(); if ( total > 0 ) { T* pVertices; HR(vertexBuffer->Lock( 0, 0, ( void** )&pVertices, 0 )); for ( size_t i = 0; i < total; ++i ) { m_Vertices[i]->set(pVertices); pVertices++; } HR(vertexBuffer->Unlock()); } m_numVertices = total; } template<class T> void DynamicVertexBuffer<T>::preRendering() { if ( m_numVertices > 0 ) { IDirect3DDevice9 * pDevice = gEngine->getDevice(); update(); if ( indexBuffer != 0 ) { indexBuffer->init(); } pDevice->SetStreamSource( 0, vertexBuffer, 0, m_vertexSize ); pDevice->SetVertexDeclaration(m_VertexDeclaration); } } template<class T> void DynamicVertexBuffer<T>::render(int numPrimitives) { if ( m_numVertices > 0 ) { IDirect3DDevice9 * pDevice = gEngine->getDevice(); if ( indexBuffer ) { HR(pDevice->SetIndices( indexBuffer->getIndexBuffer() )); HR(pDevice->DrawIndexedPrimitive( m_primitiveType, 0, 0, m_numVertices, 0, numPrimitives )); gEngine->getDrawCounter()->addIndices(indexBuffer->getSize()); gEngine->getDrawCounter()->addPrimitives(m_numVertices); } else { HR(pDevice->DrawPrimitive(m_primitiveType,0,numPrimitives)); gEngine->getDrawCounter()->addPrimitives(m_numVertices); } } } template<class T> void DynamicVertexBuffer<T>::postRendering() { } }; [/code]
  9. This is working fine now. But there is one little problem left. Actually the user can rotate the big cube around the y-axis. Once the big cube has been rotated the picking fails. It just picks up the small cubes at their original location. Do I have to rotate the picking ray as well? Or do I have to start the calculation of the picking ray with a different origin? I am a bit lost here.
  10. I was thinking along the line. But it is always better to get some support. Tonight I will try out your suggestion.
  11. Hi there, I have a probably slightly simple problem. Basically I have about 400 cubes. These cubes are all in one vertex buffer along with the indices in an index buffer. These 400 cubes are building one big cube. The user can actually rotate the big cube. That is working smoothly. But now I want to select any of these cubes with my mouse. So far I have understood that I need to calcuate a ray tracing from the mouse position in screenspace. Of course convert this ray into world space. This is not a problem. But how do I check which of my cubes was selected? I know the position of the cube. So I can also calculate each index in the vertex and index buffer to get the 24 vertices and 36 indices I have for each cube. Of course I could use the indices to get the vertices belonging to one triangle. But how to continue?
  12. There actually was a time when hungarian notation made sense. It was way back in ancient times of C. The basic idea is that you can look at the name of the variable and see what kind of type it is. Since in C you have to define the variable at the beginning. But as the variable might be used a few pages futher down you still would be able to see that iCounter is supposed to be an int variable. This is now all obsolete since you have nice IDEs. You can hoover over the varible and will get a nice popup showing the details. Also in C++ you can define the variable where you actually need it. I am developing software for 25 years now and this is definitely something that has died the deserved death.
  13. When the ball hits the wall you should: - change velocity - move the ball directly into the new direction ball.x += ball.velx * dt; ball.y += ball.vely * dt; if (ball.x &lt; 0 || ball.x &gt; SCREENW - ball.width) { ball.velx *= -1; ball.x += ball.velx * dt; } if (ball.y &lt; 0) { ball.vely *= -1; ball.y += ball.vely * dt; }
  14. Header files can be troublesome. I have found a nice resource which explained the best practice but lost the URL. So let me try to explain it. The best way is always to use forward declaration where possible and only use include when necessary. Let us look at an example: class MyClass : public BaseClass { public: Entity* getEntity(); }; Here you need to include BaseClass. The compiler and preprocessor needs to know the size and so on of your BaseClass. But for the Entity just use forward declaration. It is only a pointer so a forward declaration is perfectly fine. Include the actual header file in your cpp file. So the example looks like #include "BaseClass.h" class Entity; class MyClass : public BaseClass { public: Entity* getEntity(); }; This works nice and can help you especially when you have these cyclic dependencies. This is how I learned it and it works fine for me. If I am wrong hopefully someone will explain it.