Game Engine. Welke?

Status
Niet open voor verdere reacties.

Ultraware

Gebruiker
Lid geworden
14 mrt 2010
Berichten
268
Hallo, ik wist niet zeker of ik dit in het topic Programmeren moest plaatsen, maarja. Dit gaat wel een beetje over programmeren dus:
Ik wil een spel gaan maken dat eruit ziet als Rollercoaster Tycoon, of Zoo Tycoon, je weet wel, het klassieke Tycoon spel. Ik ga nog niet zeggen waar het spel over gaat of wat het wordt, maar:
Welke engine kan ik het beste gebruiken voor het spel? Visual C#? C++, VB 2008? Of kan ik de bestanden van bijv. Rollercoaster Tycoon ( wel 1 of 2 he! ) modden, en mijn eigen doeleinden daarvoor gebruiken? Zoja, hoe moet ik dat dan doen?
 
OK, maar waarmee zou ik de rollercoaster tycoon engine kunnen "rippen" zodat het eigenlijk hetzelfde spel is, maar met andere dingen zeg maar?
 
Niet, en dat is daarnaast nog verboden ook.

Overigens zijn C++ en Visual C# etc. geen engines, maar talen.

Als je een echte Engine wilt voor een game zou je eens kunnen kijken naar bijv:

http://irrlicht.sourceforge.net/

Of

http://www.ogre3d.org/


Houd er rekening mee dat je hier met extreem lastige en complexe applicaties te maken hebt. Ik hoop dat je al een ervaren programmeur bent, anders neem je veel te veel hooi op je vork.
 
OK, ik heb een beetje rondgekeken, maar ik geef het op, want het is veel te moeilijk, en er zijn vooral geen programmas die je helpen met het maken van een tycoon. Ik ga nog wat proberen met VB 2008, maar dat gaat waarschijnlijk niet lukken.
 
Games programmeren begint met een gigantische hoeveelheid inzet en doorzettingsvermogen. Het kost jaren om echt goed te worden in programmeren, en nog eens jaren om in je eentje een game te ontwikkelen.
 
Wist ik, daarom had ik het al opgegeven :P
Ik ben nu bezig met VB, maar is ook te moeilijk. Ik stop er mee, en ga proberen C++ te leren :D
Enne, ik dacht dat er waarschijnlijk een kant en klare engine was, waar je alles zo ongeveer kon invoeren XD
Daar hebben we eigenlijk wel behoefte aan :confused:
Nouja, ik ga C++ leren
En deze vraag is opgelost..... soort van
 
Ik ben nu bezig met VB, maar is ook te moeilijk. Ik stop er mee, en ga proberen C++ te leren

Ik wil niet te belerend overkomen, maar als je met VB stopt omdat het te moeilijk is, in combinatie met je andere posts, ziet het ernaar uit dat je nog niet over het doorzettingsvermogen beschikt oom aan C(++) te beginnen.

Als je in C(++) programmeert, dan is het -zeker als je naar grotere programma's evolueert- een must heel goed te weten hoe de taal werkt; en dat leer je spijtig genoeg niet door flashy drag-and-drop toe te passen (okee, toegegeven, er zijn uitzonderingen).
Bereid je alvast voor om de eerste weken/maanden enkel met consolevenstertjes bezig te zijn.

In VB kan je echter meteen het een en ander grafisch verwezenlijken, en hoewel de syntax imo te laks is, kan je best wel veel programmeertechnieken aanleren. Dat zorgt ervoor dat je het programmeren zelf vaak als aangenamer ervaart, wat het makkelijker maakt om door te zetten..
 
In VB kan ik al wat geavanceerdere apps maken, dus ik wil nu eens C++ gaan proberen. Ik gaf op met VB, omdat C++ logischer is om spellen mee te maken, en omdat VB me een beetje mn keel uit begon te hangen. Ik oefen er nu al 3 jaar mee :D
Dus ik wil net zoals ik VB heb geleerd ( via Youtube tutorials ) C++ gaan leren. Dit zal wel moeilijker gaan etc. maar ik ga het proberen. En met VB ben ik met mn "ultieme" app bezig, genaamd UltraOS. Kijk op mijn website maar voor meer info.
 
Dat SAI-filmpje ziet er best wel goed uit.

Voor C++ kan ik je alvast aanraden om deze tutorials van cprogramming.com te doorlopen. Ze leren mooi de verschillende basisstructuren en hun nut aan per les.

En aangezien je naar gameprogramming wil doorstromen kan je achteraf eens naar deze lessen/opdrachten kijken. Ze maken daar wel gebruik van visual C++ als IDE (installeren en opzetten in opdracht 1).
Opdracht 2 kan je al direct na de cprogramming tutorials uitvoeren en geeft je een simpele basis rond pathfinding mee. Ook de derde opdracht kan je al meteen uitvoeren, wat een eenvoudige text-based RPG oplevert.

Voor opdracht 4 en 5 wordt gebruik gemaakt van OGRE, een 3D-engine die Frats ook reeds vernoemde. De opdrachten zijn echter met eender welke engine uit te voeren.


Nog een laatste woord van advies: Bij veel beginnerstutorials wordt het gebruik van Dev-Cpp (of Dev-C++) aangeraden, omdat dit een eenvoudige IDE is; persoonlijk raad ik je die IDE ten zeerste af: hoewel die vroeger best wel goed was, ligt de ontwikkeling ervan al ruim 5 jaar stil en sterft het project een langzame dood.
Andere/Betere IDE's zijn:
  • Code::Blocks
  • Eclipse - CDT
  • NetBeans
 
Ik zou ook kiezen voor de programmeertaal C++. Eerst moet je kijken: welke eisen moet mijn engine hebben. Ik vond dat mijn engine cross platform moest zijn (windows en linux) en ik wilde het niet baseren op libraries waarvoor ik zou moeten betalen om het te gebruiken.

Je moet eerst de volgende dingen kiezen:
De programmeertaal -> ik heb gekozen voor C++

De compiler -> ik werk met wxDev-C++, ook al is deze verouderd, hij werkt nog goed genoeg voor mij en hij is heel overzichtelijk voor beginners

De grafische taal, waarmee wil je je graphics aansturen -> OpenGL of DirectX? -> ik heb gekozen voor OpenGL, en niet voor DirectX omdat dat alleen voor windows is

Een library -> je kan niet zonder een library, het kan je heel veel werk besparen om er 1 te gebruiken. Ik heb gekozen voor GLFW (zie www.glfw.org), omdat er hele goede handleidingen voor te vinden zijn, hij cross platform is en zorgt voor een aantal belangrijke dingen als keyboard/muis-input, het opent een zwart venster voor je op de goede resolutie(ja, je vergist je als je denkt dat dit heel makkelijk is om dit zelf te schrijven, zeker als je wil dat dit op linux en windows werkt), een timer functie enz.

Zelf ben ik ook nog lang niet klaar met mijn engine. Ik wil nog dingen als geluid (met OpenAL) toevoegen, een eigen server runnen voor multiplayer en nog een aantal dingen.

Hier zijn nog wat belangrijke links:

voor C++ en openGL tutorials met filmpjes:
http://xoax.net/comp/cpp/console/
http://xoax.net/comp/cpp/opengl/

andere handige links:
http://gpwiki.org
http://gpwiki.org/index.php/GLFW
http://nehe.gamedev.net/

hier heb je al vast wat code om je op weg te helpen. Dit zijn de 2 bestanden die mijn engine gebruikt om tga plaatjes te laden (gebasseerd op een artikel van gpwiki.org)

tga.cpp
[CPP]#include <GL/glfw.h>
#include "tga.h"

// THE MAIN TEXTURE LOAD FUNCTION

// Load a TGA texture
bool LoadTexture(char *TexName, GLuint TexHandle)
{
TGAImg Img; // Image loader

// Load our Texture
if(Img.Load(TexName)!=IMG_OK)
return false;

glBindTexture(GL_TEXTURE_2D,TexHandle); // Set our Tex handle as current

// Create the texture
if(Img.GetBPP()==24)
glTexImage2D(GL_TEXTURE_2D,0,3,Img.GetWidth(),Img.GetHeight(),0,GL_RGB,GL_UNSIGNED_BYTE,Img.GetImg());
else if(Img.GetBPP()==32)
glTexImage2D(GL_TEXTURE_2D,0,4,Img.GetWidth(),Img.GetHeight(),0,GL_RGBA,GL_UNSIGNED_BYTE,Img.GetImg());
else
return false;

// Specify filtering and edge actions
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

return true;
}



// OTHER TEXTURE LOAD FUNCTION USED BY ABOVE FUNCTION

TGAImg::TGAImg()
{
pImage=pPalette=pData=NULL;
iWidth=iHeight=iBPP=bEnc=0;
lImageSize=0;
}


TGAImg::~TGAImg()
{
if(pImage)
{
delete [] pImage;
pImage=NULL;
}

if(pPalette)
{
delete [] pPalette;
pPalette=NULL;
}

if(pData)
{
delete [] pData;
pData=NULL;
}
}


int TGAImg::Load(char* szFilename)
{
using namespace std;
ifstream fIn;
unsigned long ulSize;
int iRet;

// Clear out any existing image and palette
if(pImage)
{
delete [] pImage;
pImage=NULL;
}

if(pPalette)
{
delete [] pPalette;
pPalette=NULL;
}

// Open the specified file
fIn.open(szFilename,ios::binary);

if(fIn==NULL)
return IMG_ERR_NO_FILE;

// Get file size
fIn.seekg(0,ios_base::end);
ulSize=fIn.tellg();
fIn.seekg(0,ios_base::beg);

// Allocate some space
// Check and clear pDat, just in case
if(pData)
delete [] pData;

pData=new unsigned char[ulSize];

if(pData==NULL)
{
fIn.close();
return IMG_ERR_MEM_FAIL;
}

// Read the file into memory
fIn.read((char*)pData,ulSize);

fIn.close();

// Process the header
iRet=ReadHeader();

if(iRet!=IMG_OK)
return iRet;

switch(bEnc)
{
case 1: // Raw Indexed
{
// Check filesize against header values
if((lImageSize+18+pData[0]+768)>ulSize)
return IMG_ERR_BAD_FORMAT;

// Double check image type field
if(pData[1]!=1)
return IMG_ERR_BAD_FORMAT;

// Load image data
iRet=LoadRawData();
if(iRet!=IMG_OK)
return iRet;

// Load palette
iRet=LoadTgaPalette();
if(iRet!=IMG_OK)
return iRet;

break;
}

case 2: // Raw RGB
{
// Check filesize against header values
if((lImageSize+18+pData[0])>ulSize)
return IMG_ERR_BAD_FORMAT;

// Double check image type field
if(pData[1]!=0)
return IMG_ERR_BAD_FORMAT;

// Load image data
iRet=LoadRawData();
if(iRet!=IMG_OK)
return iRet;

BGRtoRGB(); // Convert to RGB
break;
}

case 9: // RLE Indexed
{
// Double check image type field
if(pData[1]!=1)
return IMG_ERR_BAD_FORMAT;

// Load image data
iRet=LoadTgaRLEData();
if(iRet!=IMG_OK)
return iRet;

// Load palette
iRet=LoadTgaPalette();
if(iRet!=IMG_OK)
return iRet;

break;
}

case 10: // RLE RGB
{
// Double check image type field
if(pData[1]!=0)
return IMG_ERR_BAD_FORMAT;

// Load image data
iRet=LoadTgaRLEData();
if(iRet!=IMG_OK)
return iRet;

BGRtoRGB(); // Convert to RGB
break;
}

default:
return IMG_ERR_UNSUPPORTED;
}

// Check flip bit
if((pData[17] & 0x20)==0)
FlipImg();

// Release file memory
delete [] pData;
pData=NULL;

return IMG_OK;
}


int TGAImg::ReadHeader() // Examine the header and populate our class attributes
{
short ColMapStart,ColMapLen;
short x1,y1,x2,y2;

if(pData==NULL)
return IMG_ERR_NO_FILE;

if(pData[1]>1) // 0 (RGB) and 1 (Indexed) are the only types we know about
return IMG_ERR_UNSUPPORTED;

bEnc=pData[2]; // Encoding flag 1 = Raw indexed image
// 2 = Raw RGB
// 3 = Raw greyscale
// 9 = RLE indexed
// 10 = RLE RGB
// 11 = RLE greyscale
// 32 & 33 Other compression, indexed

if(bEnc>11) // We don't want 32 or 33
return IMG_ERR_UNSUPPORTED;


// Get palette info
memcpy(&ColMapStart,&pData[3],2);
memcpy(&ColMapLen,&pData[5],2);

// Reject indexed images if not a VGA palette (256 entries with 24 bits per entry)
if(pData[1]==1) // Indexed
{
if(ColMapStart!=0 || ColMapLen!=256 || pData[7]!=24)
return IMG_ERR_UNSUPPORTED;
}

// Get image window and produce width & height values
memcpy(&x1,&pData[8],2);
memcpy(&y1,&pData[10],2);
memcpy(&x2,&pData[12],2);
memcpy(&y2,&pData[14],2);

iWidth=(x2-x1);
iHeight=(y2-y1);

if(iWidth<1 || iHeight<1)
return IMG_ERR_BAD_FORMAT;

// Bits per Pixel
iBPP=pData[16];

// Check flip / interleave byte
if(pData[17]>32) // Interleaved data
return IMG_ERR_UNSUPPORTED;

// Calculate image size
lImageSize=(iWidth * iHeight * (iBPP/8));

return IMG_OK;
}


int TGAImg::LoadRawData() // Load uncompressed image data
{
short iOffset;

if(pImage) // Clear old data if present
delete [] pImage;

pImage=new unsigned char[lImageSize];

if(pImage==NULL)
return IMG_ERR_MEM_FAIL;

iOffset=pData[0]+18; // Add header to ident field size

if(pData[1]==1) // Indexed images
iOffset+=768; // Add palette offset

memcpy(pImage,&pData[iOffset],lImageSize);

return IMG_OK;
}


int TGAImg::LoadTgaRLEData() // Load RLE compressed image data
{
short iOffset,iPixelSize;
unsigned char *pCur;
unsigned long Index=0;
unsigned char bLength,bLoop;

// Calculate offset to image data
iOffset=pData[0]+18;

// Add palette offset for indexed images
if(pData[1]==1)
iOffset+=768;

// Get pixel size in bytes
iPixelSize=iBPP/8;

// Set our pointer to the beginning of the image data
pCur=&pData[iOffset];

// Allocate space for the image data
if(pImage!=NULL)
delete [] pImage;

pImage=new unsigned char[lImageSize];

if(pImage==NULL)
return IMG_ERR_MEM_FAIL;

// Decode
while(Index<lImageSize)
{
if(*pCur & 0x80) // Run length chunk (High bit = 1)
{
bLength=*pCur-127; // Get run length
pCur++; // Move to pixel data

// Repeat the next pixel bLength times
for(bLoop=0;bLoop!=bLength;++bLoop,Index+=iPixelSize)
memcpy(&pImage[Index],pCur,iPixelSize);

pCur+=iPixelSize; // Move to the next descriptor chunk
}
else // Raw chunk
{
bLength=*pCur+1; // Get run length
pCur++; // Move to pixel data

// Write the next bLength pixels directly
for(bLoop=0;bLoop!=bLength;++bLoop,Index+=iPixelSize,pCur+=iPixelSize)
memcpy(&pImage[Index],pCur,iPixelSize);
}
}

return IMG_OK;
}


int TGAImg::LoadTgaPalette() // Load a 256 color palette
{
unsigned char bTemp;
short iIndex,iPalPtr;

// Delete old palette if present
if(pPalette)
{
delete [] pPalette;
pPalette=NULL;
}

// Create space for new palette
pPalette=new unsigned char[768];

if(pPalette==NULL)
return IMG_ERR_MEM_FAIL;

// VGA palette is the 768 bytes following the header
memcpy(pPalette,&pData[pData[0]+18],768);

// Palette entries are BGR ordered so we have to convert to RGB
for(iIndex=0,iPalPtr=0;iIndex!=256;++iIndex,iPalPtr+=3)
{
bTemp=pPalette[iPalPtr]; // Get Blue value
pPalette[iPalPtr]=pPalette[iPalPtr+2]; // Copy Red to Blue
pPalette[iPalPtr+2]=bTemp; // Replace Blue at the end
}

return IMG_OK;
}


void TGAImg::BGRtoRGB() // Convert BGR to RGB (or back again)
{
unsigned long Index,nPixels;
unsigned char *bCur;
unsigned char bTemp;
short iPixelSize;

// Set ptr to start of image
bCur=pImage;

// Calc number of pixels
nPixels=iWidth*iHeight;

// Get pixel size in bytes
iPixelSize=iBPP/8;

for(Index=0;Index!=nPixels;Index++) // For each pixel
{
bTemp=*bCur; // Get Blue value
*bCur=*(bCur+2); // Swap red value into first position
*(bCur+2)=bTemp; // Write back blue to last position

bCur+=iPixelSize; // Jump to next pixel
}

}


void TGAImg::FlipImg() // Flips the image vertically (Why store images upside down?)
{
unsigned char bTemp;
unsigned char *pLine1, *pLine2;
int iLineLen,iIndex;

iLineLen=iWidth*(iBPP/8);
pLine1=pImage;
pLine2=&pImage[iLineLen * (iHeight - 1)];

for( ;pLine1<pLine2;pLine2-=(iLineLen*2))
{
for(iIndex=0;iIndex!=iLineLen;pLine1++,pLine2++,iIndex++)
{
bTemp=*pLine1;
*pLine1=*pLine2;
*pLine2=bTemp;
}
}

}


int TGAImg::GetBPP()
{
return iBPP;
}


int TGAImg::GetWidth()
{
return iWidth;
}


int TGAImg::GetHeight()
{
return iHeight;
}


unsigned char* TGAImg::GetImg()
{
return pImage;
}


unsigned char* TGAImg::GetPalette()
{
return pPalette;
}
[/CPP]

tga.h
[CPP]#ifndef _TGA_H
#define _TGA_H


#include <iostream>
#include <fstream>
#include <memory.h>

#define IMG_OK 0x1
#define IMG_ERR_NO_FILE 0x2
#define IMG_ERR_MEM_FAIL 0x4
#define IMG_ERR_BAD_FORMAT 0x8
#define IMG_ERR_UNSUPPORTED 0x40

class TGAImg
{
public:
TGAImg();
~TGAImg();
int Load(char* szFilename);
int GetBPP();
int GetWidth();
int GetHeight();
unsigned char* GetImg(); // Return a pointer to image data
unsigned char* GetPalette(); // Return a pointer to VGA palette

private:
short int iWidth,iHeight,iBPP;
unsigned long lImageSize;
char bEnc;
unsigned char *pImage, *pPalette, *pData;

// Internal workers
int ReadHeader();
int LoadRawData();
int LoadTgaRLEData();
int LoadTgaPalette();
void BGRtoRGB();
void FlipImg();
};

#endif
[/CPP]
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan