I am doing a small project of drawing tool.
When button down, capture the start point. When mouse move, draw a line. When button up, capture the final point. I use line to draw a polygon, so I use array m_polygonx to store final point.x of a line, and m_polygony to store final point.y, uint m_count to count the numbers of final points.
Here is my code:
void CDrawToolView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_startRect=FALSE;
::ClipCursor(NULL);
dc.MoveTo(m_startPoint);
dc.LineTo(m_OldPoint);
dc.MoveTo(m_startPoint);
dc.LineTo(point);
m_count++;
m_polygonx[m_count] = point.x;
m_polygony[m_count] = point.y;
}
And then I pass the array to a dialog.
In my calling function:
void CDrawToolView::OnEditProperty()
{
CPropertyDlg dlg;
dlg.origin_x = m_startPoint.x;
dlg.origin_y = m_startPoint.y;
dlg.count = m_count;
for (int i=0; i < m_count ; i++)
{
dlg.polygonx[i] = m_polygonx[i];
dlg.polygony[i] = m_polygony[i];
}
if (dlg.DoModal() == IDOK)
{
m_startPoint.x = dlg.origin_x;
m_startPoint.y = dlg.origin_y;
m_count = dlg.count;
for (int i=0; i < dlg.count ; i++)
{
m_polygonx[i] = dlg.polygonx[i];
m_polygony[i] = dlg.polygony[i];
}
}
}
But the array does not stored and passed successfully. Could some one help me?
Related
I want to display list items in a separate window. But when the window opens it doesn't display the list. I can click the list item but I cannot see it. If I click on data it appears one by one.Also, when I scroll down the list it displays the data.
I have tired using
m_bList_index.UpdateData(FALSE);
m_bList_index.UpdateWindow();
m_bList.UpdateData(FALSE);
m_bList.UpdateWindow();
at the last of the DisplayList() function, but that didn't resolve the issue. Below is the code which I want to edit.
CListBox m_bList_index;
CMyListBox m_bList;
BOOL CBatch::OnInitDialog()
{
CDialog::OnInitDialog();
m_status.Empty();
m_bIndex.Empty();
m_elapsed_time.Empty();
m_estimated_time.Empty();
CenterWindow();
m_bList.CreateColumn();
DisplayList();
return TRUE;
// return TRUE unless you set the focus to a control
}
void CBatch::DisplayList()
{
unsigned int size;
m_bList_title.ResetContent();
m_bList_title.SetHorizontalExtent(2000);
m_bList_title.InsertString(0, theApp.m_pFieldBTitleStr);
theApp.bCheckList->SetSortingType(theApp.checkList->GetSortingType());
theApp.bCheckList->Sort();
size = theApp.bCheckList->GetSize();
m_bList_index.SetRedraw(FALSE);
m_bList_index.ResetContent();
m_bList_index.SetHorizontalExtent(2000);
m_bList.SetRedraw(FALSE);
m_bList.DeleteAllItems();
m_bList.SetHorizontalExtent(2000);
char ColumnName[256];
char strColumnValue[256];
double fColumnValue;
for (unsigned int i = 0; i < size; i++)
{
char buffer[255];
int index = 0;
if(m_bList.m_SerialNo)
{
sprintf(buffer,"%d",i+1);
m_bList.InsertItem(i, buffer,0);
index = 0;
}
else
{
theApp.bCheckList->m_checkArray[i]->get((CV_CHECK_FIELD)(m_bList.ListColumns[0]),buffer);
m_bList.InsertItem(i, buffer,0);
index = 1;
}
for(; index < m_bList.NoofColumns; index++)
{
LV_COLUMN rightjust;
rightjust.mask = LVCF_FMT;
rightjust.fmt = LVCFMT_RIGHT;
m_bList.SetColumn(index+m_bList.m_SerialNo,&rightjust);
memset(buffer,0x0,256);
theApp.bCheckList->m_checkArray[i]->get((CV_CHECK_FIELD)(m_bList.ListColumns[index]),buffer);
if ( (m_bList.ListColumns[index] == CV_CHECK_FIELD_FILELOCATION) ||
(m_bList.ListColumns[index] == CV_CHECK_FIELD_POSTED_DATE) ||
(m_bList.ListColumns[index] == CV_CHECK_FIELD_STATUS))
strcpy(buffer, buffer);
}
m_bList.SetItemText(i,index+m_bList.m_SerialNo,buffer);
}
}
m_bList.SetSel(0, TRUE);
m_bList.SetRedraw(TRUE);
m_bList_index.SetRedraw(TRUE);
UpdateData(FALSE);
}
I want to delete old images I created in a for loop.
The first time clicking the Button the images are created. The second time or third, whatever, the old Images that were created should now be deleted (before the loop) and then directly recreated in the loop.
Because I am getting the Image properties from the database and when someone changed something in the database you should be enabled to get the newest Image properties from the database.
I tried it with delete Image[i], free() and delete[] (whole Array) but I am always getting an Access Violation Error. Here is my following code:
TImage *Image[c]= ; //c is 5
I want to delete the old Images here and then create the new in the loop below
for (int i = 0; i < c; i++)
{
str = " Test "
Image[i] = new TImage(this);
Image[i]->Parent = BoardItem ;
Image[i]->Height = 20 ;
Image[i]->Width = 20 ;
Image[i]->Position->X = d ; // The program asks you the coordinate at the begining of a new loop
Image[i]->Position->Y = e ;
Image[i]->Bitmap = Icon->Bitmap ;
Image[i]->StyleName = str ;
Image[i]->OnClick = ImageClick ;
}
#Mykola i pulled the example out of my code , so it is not that complicated to understand. in button2 i want to delete now all images that are on tabitem1
void __fastcall TForm2::Button2Click(TObject *Sender)
{
TImage *Image[5] ;
for (int i = 0; i < c; i++) {
Image[i] = new TImage(this);
Image[i]->Parent = TabItem1 ;
Image[i]->Height = 20 ;
Image[i]->Width = 20 ;
Image[i]->Position->X = 10 ;
Image[i]->Position->Y = 10 ;
Image[i]->Bitmap = Image1->Bitmap ;
Image[i]->StyleName = "Something" ;
Image[i]->OnClick = ImageClick ;
}
}
//--------------------------------------------------------------------------
void __fastcall TForm2::ImageClick(TObject *Sender)
{
TImage *Img = dynamic_cast<TImage *>(Sender);
ShowMessage(Img->StyleName);
}
//--------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
}
You must delete single image by simple delete operator like:
for (int i = 0; i < c; i++)
{
delete Image[i];
// NULL deleted pointer
Image[i] = NULL;
}
Access Violation also may be caused because you still use this images somewhere in your code. And why did you want delete this images? As they are pointers you may simple renew values.
To reserve values for unpredictable amount of pointers TImage* you can use:
TImage** ppImage= NULL;
than create amount of pointers you want:
ppImage = new TImage*[c];
after that you may work with those pointers like you did before.
You could go like this. In the header of the class you define the array and some methods:
int c; // Maximum (better as define?)
TImage *Image[];
bool CheckImagesLoaded();
void DeleteAllImages();
void CreateImage(int nIndex, AnsiString str);
void CreateAllImages();
Then, in the constructor you init the array:
c = 5;
for (int i = 0; i < c; i++)
{
Image[i] = NULL;
}
Now you can do the check if images were already loaded:
bool TForm1::CheckImagesLoaded()
{
return Image[0]!=NULL;
}
To delete them all:
void TForm1::DeleteAllImages()
{
for (int i = 0; i < c; i++)
{
delete Image[i];
Image[i] = NULL;
}
}
Create a a single image like this (you have to expand the parameters as you need them):
void TForm1::CreateImage(int nIndex, AnsiString str)
{
Image[nIndex] = new TImage(this);
/*Image[nIndex]->Parent = BoardItem ;
Image[nIndex]->Height = 20 ;
Image[nIndex]->Width = 20 ;
Image[nIndex]->Position->X = d ; // The programm asks you the coordinate at the begining of a new loop
Image[nIndex]->Position->Y = e ;
Image[nIndex]->Bitmap = Icon->Bitmap ;
Image[nIndex]->StyleName = str ;
Image[nIndex]->OnClick = ImageClick ;
*/
}
And in a loop you can create all images as you like:
void TForm1::CreateAllImages()
{
AnsiString str = " Test ";
for (int i = 0; i < c; i++)
{
// load data from anywhere...
CreateImage(i, str);
}
}
So, now you can operate in the Button-Event.
Delete all old Images, if existing.
Create all new Images.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Delete old Images, if existing
if (CheckImagesLoaded())
{
DeleteAllImages();
}
// Create new Images
CreateAllImages();
}
Hope this helps...
I would like to use glutTimerFunc to move the camera around the scene which is composed of some mesh models. The camera path is build with a Bezier curve like the following:
if(sel == MODE_CAMERA_MOTION) {
mode = MODE_CAMERA_MOTION;
stepsCounter = 0;
// Building camera track
int i, j, k;
for(j=0; j<MAX_CV; j++) {
tmpCV[j][0] = CV[j][0];
tmpCV[j][1] = CV[j][1];
tmpCV[j][2] = CV[j][2];
}
for(i=0; i<STEPS; i++) {
for(j=1; j<MAX_CV; j++) {
for(k=0; k<MAX_CV-j; k++) {
lerp(i/(float)(STEPS*10), tmpCV[k], tmpCV[k+1], tmpCV[k]);
}
}
cameraPosition[i][0] = tmpCV[0][0];
cameraPosition[i][1] = tmpCV[0][1];
cameraPosition[i][2] = tmpCV[0][2];
}
glutTimerFunc(250, moveCamera, STEPS);
}
where the moveCamera function is:
void moveCamera() {
if (mode == MODE_CAMERA_MOTION) {
camE[0] = cameraPosition[stepsCounter][0];
camE[1] = cameraPosition[stepsCounter][1];
camE[2] = cameraPosition[stepsCounter][2];
if(stepsCounter < STEPS) {
stepsCounter++;
}
else {
/* come back to the first point */
camE[0] = 8.8;
camE[1] = 4.9;
camE[2] = 9.0;
stepsCounter = 0;
}
glutPostRedisplay();
}
}
But nothing moves. Maybe I have misunderstood the behaviour of that function.
Where am I wrong?
The prototype to the function passed to glutTimerFunc should be
void (*func)(int value)
Where the last parameter of glutTimerFunc is the passed value. So your moveCamera should be:
void moveCamera( int STEPS )
Also, even so, the moveCamera function will be called once. You need to reregister at end of execution. This might be a possible solution:
// instead of global STEPS and stepsCounter, we decrement at reexecution
void moveCamera( int STEPS ) {
... do stuff
glutTimerFunc(250, moveCamera, STEPS-1 );
}
I am using tile mapping and have my map class in place to draw the map by using an array of sprites. i have it to set the position of the sprite and then create a bounding box array around it and then draw the sprite.
i then have a collision class which gets the player bounding box and compares it with each bounding box for the sprite. i have an array called platformboundingBox. this stores each bounding box of each sprite in the array. however when i compare the values it seems that the platform bounding box has no values in any of the locations yet the i have checked that the values of each sprite go into the bounding box array.
here is my map class. see the drawmap and collision functions to take a look. if anyone can help i would really appreciate it.
#include "Map.h"
#include "Block.h"
#include <sstream>
using namespace std;
Map::Map()
{
//map ctor;
}
Map::~Map()
{
// map dtor
}
void Map::Initialise(const char *filename)
{
if(!BlockImage.LoadFromFile("Images/block.png"))
cout<<endl<<"failed to load block image"<<endl;
if(!GemImage.LoadFromFile("Images/Gem.png"))
cout<<endl<<"failed to load Gem Image"<<endl;
if(!leftBlockImage.LoadFromFile("Images/blockLeft.png"))
cout<<endl<<"failed to load left block Image"<<endl;
if(!rightBlockImage.LoadFromFile("Images/blockRight.png"))
cout<<endl<<"failed to load right block Image"<<endl;
std::ifstream openfile(filename);
std::vector <int> tempvector;
std::string line;
while(std::getline(openfile, line))
{
for(int i =0; i < line.length(); i++)
{
if(line[i] != ' ') // if the value is not a space
{
char value = line[i];
tempvector.push_back(value - '0');
}
}
mapVector.push_back(tempvector); // push back the value of the temp vector into the map vector
tempvector.clear(); // clear the temp vector readt for the next value
}
}
void Map::DrawMap(sf::RenderWindow &Window)
{
Player playermap;
for(i = 0; i < mapVector.size(); i++)
{
for(j = 0; j < mapVector[i].size(); j++)
{
if(mapVector[i][j] == 1)
{
sprite[j].SetImage(BlockImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Bottom = sprite[j].GetPosition().y;
platformBoundingBox[j].Left = sprite[j].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[j].GetPosition().x;
Window.Draw(sprite[j]);
}
else if(mapVector[i][j] == 2)
{
sprite[j].SetImage(GemImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Top = sprite[j].GetPosition().y - 5;
platformBoundingBox[j].Bottom = sprite[j].GetPosition().y;
platformBoundingBox[j].Left = sprite[j].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[j].GetPosition().x;
Window.Draw(sprite[j]);
}
else if(mapVector[i][j] == 3)
{
sprite[j].SetImage(leftBlockImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Top = sprite[i].GetPosition().y - 5;
platformBoundingBox[j].Bottom = sprite[i].GetPosition().y;
platformBoundingBox[j].Left = sprite[i].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[i].GetPosition().x;
Window.Draw(sprite[j]);
}
else if(mapVector[i][j] == 4)
{
sprite[j].SetImage(rightBlockImage);
sprite[j].SetPosition(j * BLOCKSIZE, i * BLOCKSIZE);
platformBoundingBox[j].Top = sprite[i].GetPosition().y - 5;
platformBoundingBox[j].Bottom = sprite[i].GetPosition().y;
platformBoundingBox[j].Left = sprite[i].GetPosition().x - 5;
platformBoundingBox[j].Right = sprite[i].GetPosition().x;
Window.Draw(sprite[j]);
}
}
}
}
void Map::collisions(float x, float y)
{
Player playermap;
this->x = x;
this->y = y;
playerboundingbox.Top = y - 5;
playerboundingbox.Bottom = y ;
playerboundingbox.Left = x - 5;
playerboundingbox.Right = x;
for(i = 0; i < 100; i++)
{
if(playerboundingbox.Intersects(platformBoundingBox[i]))
cout << " praise the lord";
}
}
Please switch to SFML 2 because 1.6 have a lot of bugs.
Let's say you create a class named handler where you will put:
handler::handler()
// window initialization
Map Map; // here initialize the Map class
/* why don't use Map::Map( ctor) for initialization? */
// player initialization
// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
//draw player
Map.DrawMap(); // also need to improve the drawing for less lag
window.display();
update(Map &Map, Player &Player);
// every time to use & because without the compiler will create another object
}
}
update(Map &Map, Player &Player)
{
// verify if exists some interacts
if (intersects(Map &Map, Player &Player))
{
//verify from where and put to the correct position
/* e.g: if we have a collide with a down tile map will say something like this:
Player.setPosition(Player.getPosition().x, (Player.getGlobalBounds().top+Player.getGlobalBounds().height)-(Map.getGlobalBounds().top-(Player.getGlobalBounds().top+Player.getGlobalBounds().height)); */
}
}
intersects(Map &Map, Player &Player)
{
sf::FloatRect fPlayer = Player.getGlobalBounds();
for (int i=0; i<Map.NrOfYourTiles; ++i)
{
sf::FloatRect fMap = YourTile.getGlobalBounds();
if (fPlayer.intersects(fMap))
return 1;
}
return 0;
}
Hope this will help you( the code is in SFML 2.0). You can find a lot more help on forums of the creator sfml-dev.org.
I'm working on a prototype for a shmup game in C++ using SDL...Right now I'm just trying to get the basics working without using classes. Now, I have it so it shoots multiple bullets, but it behaves strangely which I believe is because of the way the counter is reset...The bullets will appear and disappear, and some will keep blinking in the original spot they were shot at, and there will sometimes be a delay before any can be shot again even if the limit isn't on the screen...And sometimes the player character will suddenly jump way to the right and only be able to move up and down. How do I fix this so it smoothly shoots? I've included all relevent code...
[edit] Please note that I intend on cleaning it up and moving it all to a class once I get this figured out...This is just a simple prototype so I can have the basics of the game programmed in.
[edit2] ePos is the enemy position, and pPos is the player position.
//global
SDL_Surface *bullet[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
bool shot[10];
int shotCount = 0;
SDL_Rect bPos[10];
//event handler
case SDLK_z: printf("SHOT!"); shot[shotCount] = true; ++shotCount; break;
//main function
for(int i = 0; i <= 9; i++)
{
shot[i] = false;
bullet[i] = IMG_Load("bullet.png");
}
//game loop
for(int i = 0; i <= shotCount; i++)
{
if(shot[i] == false)
{
bPos[i].x = pPos.x;
bPos[i].y = pPos.y;
}
if(shot[i] == true)
{
bPos[i].y -= 8;
SDL_BlitSurface(bullet[i], NULL, screen, &bPos[i]);
if( (bPos[i].y + 16 == ePos.y + 16) || (bPos[i].x + 16 == ePos.x + 16) )
{
shot[i] = false;
}
else if(bPos[i].y == 0)
{
shot[i] = false;
}
}
}
if(shotCount >= 9) { shotCount = 0; }
Here is something like I was suggesting in the comment. It was just written off the top of my head but it gives you a general idea of what I'm talking about..
class GameObject
{
public:
int x;
int y;
int width;
int height;
int direction;
int speed;
GameObject()
{
x = 0;
y = 0;
width = 0;
height = 0;
direction = 0;
speed = 0;
}
void update()
{
// Change the location of the object.
}
bool collidesWidth(GameObject *o)
{
// Test if the bullet collides with Enemy.
// If it does, make it invisible and return true
}
}
GameObject bullet[10];
GameObject enemy[5];
while(true)
{
for(int x=0; x<=10;x++)
{
bullet[x].update();
for(int y=0;y<=5;y++)
{
if(bullet[x].collidesWith(&enemy[y])
{
// Make explosion, etc, etc.
}
}
}
}