Vala/Clutter texture loading with thread - c++

I am trying to load image files in vala/clutter while running a timeout animation, using "image.set_load_async" stops the animation for a while when the file loads are requested. This is the source:
// valac --thread --pkg clutter-1.0 --pkg=gio-2.0 test_1.vala -o test_1
using Clutter;
class SlideImage : Clutter.Actor {
protected Texture image = new Texture ();
public int loaded = 0;
public SlideImage (string file) {
try {
loaded = 1;
image.set_load_async (true);
image.load_finished.connect((t, a) => {
loaded = 2;
this.add_actor (image);
});
image.set_from_file (file);
} catch (Error e) {
warning("Error setting SlideImageReflected gradient : %s", e.message);
}
}
}
class ClutterSlideShow {
protected Stage stage;
protected int width = 800;
protected int height =700;
protected string[] file_names = {};
private int file_pointer = 0;
private int counter = 0;
private SlideImage showA = null;
private SlideImage showB = null;
private SlideImage showC = null;
private SlideImage showD = null;
private SlideImage showE = null;
public ClutterSlideShow (string folder) {
try {
var directory = File.new_for_path (folder);
var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME,0);
FileInfo file_info;
while ((file_info = enumerator.next_file ()) != null) {
file_names += folder+"/"+file_info.get_name ();
}
} catch (Error e) {
stderr.printf ("Error ClutterSlideShow listing files: %s\n", e.message);
}
stage = Stage.get_default ();
stage.hide.connect (Clutter.main_quit);
stage.color = Color () { red = 0, green = 0, blue = 0, alpha = 255 };;
stage.set_size (width, height);
stage.show_all ();
}
protected string get_next_file () {
file_pointer++;
if (file_pointer > file_names.length) file_pointer = 1;
return file_names[file_pointer-1];
}
public void start () {
Timeout.add (15, run);
}
private bool run () {
if (showA == null) {
showA = new SlideImage (get_next_file ());
showA.set_x (0);
showA.set_y (0);
} else if (showA.loaded == 2) {
stage.add_actor (showA);
showA.loaded = 3;
} else if (showA.loaded == 3) {
showA.set_y (showA.get_y () + 1);
counter++;
if (counter==100) {
showB = new SlideImage (get_next_file ());
showB.set_x (100);
showB.set_y (0);
stage.add_actor (showB);
showC = new SlideImage (get_next_file ());
showC.set_x (200);
showC.set_y (0);
stage.add_actor (showC);
showD = new SlideImage (get_next_file ());
showD.set_x (300);
showD.set_y (0);
stage.add_actor (showD);
showE = new SlideImage (get_next_file ());
showE.set_x (400);
showE.set_y (0);
stage.add_actor (showE);
}
}
return true;
}
}
int main (string[] args) {
if (Thread.supported () == false) {
stderr.printf ("Threads are not supported!\n");
return -1;
}
var result = init (ref args);
if (result != Clutter.InitError.SUCCESS) {
stderr.printf("Error: %s\n", result.to_string());
return 1;
}
var slide_show = new ClutterSlideShow ("/usr/share/backgrounds/");
slide_show.start ();
Clutter.main ();
return 0;
}
I have also tried to use "threads" but I get a "Segmentation fault (core dumped)" that I don't know how to debug or fix. This is the example:
// valac --thread --pkg clutter-1.0 --pkg=gio-2.0 test_2.vala -o test_2
using Clutter;
class SlideImage : Clutter.Actor {
protected Texture image = new Texture ();
public int loaded = 0;
public SlideImage (string file) {
loaded = 1;
load_image_in_background.begin(file, (obj, res) => {
try {
loaded = 2;
this.add_actor (image);
} catch (ThreadError e) {
string msg = e.message;
stderr.printf(#"Thread error: $msg\n");
}
});
}
async void load_image_in_background (string file) throws ThreadError {
SourceFunc callback = load_image_in_background.callback;
ThreadFunc<void*> run = () => {
try {
// Help ! The next line results in "Segmentation fault"
image.set_from_file (file);
} catch (Error e) {
warning("Error setting SlideImage texture : %s", e.message);
}
Idle.add((owned) callback);
return null;
};
Thread.create<void*>(run, false);
yield;
}
}
class ClutterSlideShow {
protected Stage stage;
protected int width = 800;
protected int height =700;
protected string[] file_names = {};
private int file_pointer = 0;
private int counter = 0;
private SlideImage showA = null;
private SlideImage showB = null;
private SlideImage showC = null;
private SlideImage showD = null;
private SlideImage showE = null;
public ClutterSlideShow (string folder) {
try {
var directory = File.new_for_path (folder);
var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME,0);
FileInfo file_info;
while ((file_info = enumerator.next_file ()) != null) {
file_names += folder+"/"+file_info.get_name ();
}
} catch (Error e) {
stderr.printf ("Error ClutterSlideShow listing files: %s\n", e.message);
}
stage = Stage.get_default ();
stage.hide.connect (Clutter.main_quit);
stage.color = Color () { red = 0, green = 0, blue = 0, alpha = 255 };;
stage.set_size (width, height);
stage.show_all ();
}
protected string get_next_file () {
file_pointer++;
if (file_pointer > file_names.length) file_pointer = 1;
return file_names[file_pointer-1];
}
public void start () {
Timeout.add (15, run);
}
private bool run () {
if (showA == null) {
showA = new SlideImage (get_next_file ());
showA.set_x (0);
showA.set_y (0);
} else if (showA.loaded == 2) {
stage.add_actor (showA);
showA.loaded = 3;
} else if (showA.loaded == 3) {
showA.set_y (showA.get_y () + 1);
counter++;
if (counter==100) {
showB = new SlideImage (get_next_file ());
showB.set_x (100);
showB.set_y (0);
stage.add_actor (showB);
showC = new SlideImage (get_next_file ());
showC.set_x (200);
showC.set_y (0);
stage.add_actor (showC);
showD = new SlideImage (get_next_file ());
showD.set_x (300);
showD.set_y (0);
stage.add_actor (showD);
showE = new SlideImage (get_next_file ());
showE.set_x (400);
showE.set_y (0);
stage.add_actor (showE);
}
}
return true;
}
}
int main (string[] args) {
if (Thread.supported () == false) {
stderr.printf ("Threads are not supported!\n");
return -1;
}
var result = init (ref args);
if (result != Clutter.InitError.SUCCESS) {
stderr.printf("Error: %s\n", result.to_string());
return 1;
}
var slide_show = new ClutterSlideShow ("/usr/share/backgrounds/");
slide_show.start ();
Clutter.main ();
return 0;
}

The execution "stop" is produced due two reasons:
The file load (can be threaded)
The image/actor creation (can't be threaded but improved)
I received help from an expert (thanks Victor), the next code improves it with:
Threads the file load
Scales the image to its final "clutter" size
This is the code:
/**
* Build with:
* valac --thread --pkg clutter-1.0 --pkg gio-2.0 --pkg gdk-3.0 --target-glib=2.32 test_2.vala -o test_2
*/
const string SLIDESHOW_PATH = "/usr/share/backgrounds";
public class SlideImage : Clutter.Actor {
public bool ready { get; private set; default = false; }
private Clutter.Image image;
private Thread thread;
public SlideImage (File file, int width, int height) {
load_image_async.begin (file, width, height, (obj, res) => {
if (image == null)
return;
set_size (width, height);
set_content_scaling_filters (Clutter.ScalingFilter.TRILINEAR,
Clutter.ScalingFilter.LINEAR);
set_content_gravity (Clutter.ContentGravity.CENTER);
set_content (image);
ready = true;
});
}
private async void load_image_async (File file, int width, int height) {
var pixbuf = yield load_pixbuf_from_file_async (file);
if (pixbuf != null) {
image = new Clutter.Image ();
try {
float relation_w = pixbuf.get_width () / width;
float relation_h = pixbuf.get_height () / height;
float offset_x = 0.0f;
float offset_y = 0.0f;
float scale = 1.0f;
if (relation_w > relation_h) {
scale = (float) height / (float) pixbuf.get_height ();
if (pixbuf.get_width () > width)
offset_x = -((float) ((pixbuf.get_width () * scale) - width)) / 2.0f;
} else {
scale = (float) width / (float) pixbuf.get_width ();
if (pixbuf.get_height () > height)
offset_y = -((float) ((pixbuf.get_height () * scale) - height)) / 2.0f;
}
var pixbuf_scaled = new Gdk.Pixbuf (pixbuf.get_colorspace (),
pixbuf.get_has_alpha (),
pixbuf.get_bits_per_sample (),
width,
height);
pixbuf.scale (pixbuf_scaled, 0, 0, width, height, offset_x, offset_y, scale, scale, Gdk.InterpType.BILINEAR);
image.set_data (pixbuf_scaled.get_pixels (),
pixbuf_scaled.get_has_alpha () ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGB_888,
pixbuf_scaled.get_width (),
pixbuf_scaled.get_height (),
pixbuf_scaled.get_rowstride ());
} catch (Error err) {
warning ("Could not set image from pixbuf: %s", err.message);
image = null;
}
}
}
private async Gdk.Pixbuf? load_pixbuf_from_file_async (File file) {
SourceFunc callback = load_pixbuf_from_file_async.callback;
Gdk.Pixbuf? pixbuf = null;
ThreadFunc<void*> thread_func = () => {
try {
pixbuf = new Gdk.Pixbuf.from_file (file.get_path ());
message ("loaded pixbuf");
} catch (Error e) {
warning ("Error loading pixbuf: %s", e.message);
}
Idle.add ((owned) callback);
return null;
};
thread = new Thread<void*> ("load-pixbuf-in-background", thread_func);
yield;
return pixbuf;
}
}
public class ClutterSlideShow {
private const int WIDTH = 800;
private const int HEIGHT = 600;
private int counter = 0;
private List<File> files;
private Clutter.Stage stage;
private SlideImage showA;
private SlideImage showB;
private SlideImage showC;
private SlideImage showD;
private SlideImage showE;
public ClutterSlideShow (string folder) {
load_files (File.new_for_path (folder));
init_stage ();
}
public void start () {
Timeout.add (15, run);
}
protected File? get_next_file () {
var file = files.nth_data (0);
if (file != null)
files.remove (file);
return file;
}
private void load_files (File directory) {
files = new List<File> ();
try {
var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME,0);
FileInfo file_info;
while ((file_info = enumerator.next_file ()) != null) {
var child_file = directory.get_child (file_info.get_name ());
files.prepend (child_file);
}
} catch (Error e) {
warning (e.message);
}
}
private void init_stage () {
stage = new Clutter.Stage ();
stage.background_color = Clutter.Color () { red = 0, green = 0, blue = 0, alpha = 255 };
stage.set_size (WIDTH, HEIGHT);
stage.show ();
stage.hide.connect (Clutter.main_quit);
}
private bool run () {
if (showA == null) {
showA = new SlideImage (get_next_file (), 400, 400);
showA.x = 0;
showA.y = 0;
} else if (showA.get_parent () != stage) {
stage.add_child (showA);
} else if (showA.ready) {
showA.set_y (showA.get_y () + 1);
counter++;
if (counter == 50) {
showB = new SlideImage (get_next_file (), 400, 400);
showB.set_x (100);
showB.set_y (0);
stage.add_child (showB);
showC = new SlideImage (get_next_file (), 400, 400);
showC.set_x (200);
showC.set_y (0);
stage.add_child (showC);
showD = new SlideImage (get_next_file (), 400, 400);
showD.set_x (300);
showD.set_y (0);
stage.add_child (showD);
showE = new SlideImage (get_next_file (), 400, 400);
showE.set_x (400);
showE.set_y (0);
stage.add_child (showE);
}
}
return true;
}
}
void main (string[] args) {
var result = Clutter.init (ref args);
if (result != Clutter.InitError.SUCCESS)
error ("Failed to init clutter: %s", result.to_string ());
var slide_show = new ClutterSlideShow (SLIDESHOW_PATH);
slide_show.start ();
Clutter.main ();
}

Related

Cpp sdl game goes black screen after consistent amount of time [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 15 hours ago.
Improve this question
I am making a Cpp sdl game which launches as it should and is playable but only for about 7 second as after that the screen goes black. If I keep the game running with black screen it eventually shows LLVM ERROR: out of memory. While using local windows debugger in Visual Studio I get:
Exception thrown at 0x71002A85 (SDL2_ttf.dll) in game.exe: 0xC0000005: Access violation reading location 0x00000000
and/or
Unhandled exception at 0x7A6C3ED8 (nvoglv32.dll) in game.exe: Fatal program exit requested
Not sure if this information is of any use but changing SDL_Delay() from 1 to higher value e.g. 100, extends the amount of time it takes before the screen goes black. Also changing the SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED) from '-1' to '1' extends the time it takes for the game to go black screen.
I tried different versions of SDL libraries and I don't think its a hardware issue. I used Visual Studio performance profiler and the CPU and GPU usage was normal. Performance profiler did show a 1.8 GB for process memory which did seem quite high, perhaps it's because of inefficient code(?).
I included some of the code and a snapshot.
main.cpp:
int main(int argc, char **argv)
{
/* initialize SDL */
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
assert(0 && "Failed to initialize video!");
exit(-1);
}
SDL_Window* window = SDL_CreateWindow("Pacman", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1024, 768, SDL_WINDOW_OPENGL);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); //changing from -1 to 1 increase the amout of time the app runs before black screen
if(!window)
{
assert(0 && "Failed to create window!");
exit(-1);
}
IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
if (TTF_Init() == -1)
{
assert(0 && "Failed to create ttf!");
exit(-1);
}
Drawer* drawer = Drawer::Create(window, renderer);
Pacman* pacman = Pacman::Create(drawer);
float lastFrame = (float) SDL_GetTicks() * 0.001f;
SDL_Event event;
while (SDL_PollEvent(&event) >= 0)
{
float currentFrame = (float) SDL_GetTicks() * 0.001f;
float elapsedTime = currentFrame - lastFrame;
if (!pacman->Update(elapsedTime))
break;
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
pacman->Draw();
lastFrame = currentFrame;
SDL_RenderPresent(renderer);
SDL_Delay(1);
}
delete pacman;
delete drawer;
TTF_Quit();
IMG_Quit();
SDL_Quit( );
return 0;
}
Drawer.cpp:
Drawer* Drawer::Create(SDL_Window* aWindow, SDL_Renderer* aRenderer)
{
Drawer* drawer = new Drawer(aWindow, aRenderer);
if (!drawer->Init())
{
delete drawer;
drawer = NULL;
}
return drawer;
}
Drawer::Drawer(SDL_Window* aWindow, SDL_Renderer* aRenderer)
: myWindow(aWindow)
, myRenderer(aRenderer)
, world()
{
}
Drawer::~Drawer(void)
{
}
bool Drawer::Init()
{
if (!myWindow)
return false;
return true;
}
void Drawer::Draw(const char* anImage, int aCellX, int aCellY)
{
SDL_Surface* surface = IMG_Load( anImage ) ;
if (!surface)
return;
SDL_Texture* optimizedSurface = SDL_CreateTextureFromSurface(myRenderer, surface);
SDL_Rect sizeRect;
sizeRect.x = 0 ;
sizeRect.y = 0 ;
sizeRect.w = surface->w ;
sizeRect.h = surface->h ;
SDL_Rect posRect;
posRect.x = aCellX;
posRect.y = aCellY;
posRect.w = sizeRect.w;
posRect.h = sizeRect.h;
SDL_RenderCopy(myRenderer, optimizedSurface, &sizeRect, &posRect);
}
void Drawer::DrawText(const char* aText, const char* aFontFile, int aX, int aY)
{
TTF_Font* font = TTF_OpenFont(aFontFile, 24);
if (font == nullptr) {
// Handle font loading error here (e.g. log an error message, throw an exception, etc.)
return;
}
SDL_Color fg = { 255, 0, 0, 255 };
SDL_Surface* surface = TTF_RenderText_Solid(font, aText, fg);
SDL_Texture* optimizedSurface = SDL_CreateTextureFromSurface(myRenderer, surface);
SDL_Rect sizeRect;
sizeRect.x = 0;
sizeRect.y = 0;
sizeRect.w = surface->w;
sizeRect.h = surface->h;
SDL_Rect posRect;
posRect.x = aX;
posRect.y = aY;
posRect.w = sizeRect.w;
posRect.h = sizeRect.h;
SDL_RenderCopy(myRenderer, optimizedSurface, &sizeRect, &posRect);
SDL_DestroyTexture(optimizedSurface);
SDL_FreeSurface(surface);
TTF_CloseFont(font);
}
world.cpp:
World::World(void)
{
}
World::~World()
{
for (auto tile : myPathmapTiles)
{
delete tile;
}
for (auto dot : myDots)
{
delete dot;
}
for (auto bigDot : myBigDots)
{
delete bigDot;
}
}
void World::Init()
{
InitPathmap();
InitDots();
InitBigDots();
}
bool World::InitPathmap()
{
std::string line;
std::ifstream myfile ("map.txt");
if (myfile.is_open())
{
int lineIndex = 0;
while (! myfile.eof() )
{
std::getline (myfile,line);
for (unsigned int i = 0; i < line.length(); i++)
{
PathmapTile* tile = new PathmapTile(i, lineIndex, (line[i] == 'x'));
myPathmapTiles.push_back(tile);
}
lineIndex++;
}
myfile.close();
}
return true;
}
bool World::InitDots()
{
std::string line;
std::ifstream myfile ("map.txt");
if (myfile.is_open())
{
int lineIndex = 0;
while (! myfile.eof() )
{
std::getline (myfile,line);
for (unsigned int i = 0; i < line.length(); i++)
{
if (line[i] == '.')
{
Dot* dot = new Dot(Vector2f(i * 22.0f, lineIndex * 22.0f));
myDots.push_back(dot);
}
}
lineIndex++;
}
myfile.close();
}
return true;
}
bool World::InitBigDots()
{
std::string line;
std::ifstream myfile ("map.txt");
if (myfile.is_open())
{
int lineIndex = 0;
while (! myfile.eof() )
{
std::getline (myfile,line);
for (unsigned int i = 0; i < line.length(); i++)
{
if (line[i] == 'o')
{
BigDot* dot = new BigDot(Vector2f(i * 22.0f, lineIndex * 22.0f));
myBigDots.push_back(dot);
}
}
lineIndex++;
}
myfile.close();
}
return true;
}
void World::Draw(Drawer* aDrawer)
{
aDrawer->Draw("playfield.png");
for(std::list<Dot*>::iterator list_iter = myDots.begin(); list_iter != myDots.end(); list_iter++)
{
Dot* dot = *list_iter;
dot->Draw(aDrawer);
}
for(std::list<BigDot*>::iterator list_iter = myBigDots.begin(); list_iter != myBigDots.end(); list_iter++)
{
BigDot* dot = *list_iter;
dot->Draw(aDrawer);
}
}
bool World::TileIsValid(int anX, int anY)
{
for(std::list<PathmapTile*>::iterator list_iter = myPathmapTiles.begin(); list_iter != myPathmapTiles.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
if (anX == tile->myX && anY == tile->myY && !tile->myIsBlockingFlag)
return true;
}
return false;
}
bool World::HasIntersectedDot(const Vector2f& aPosition)
{
for(std::list<Dot*>::iterator list_iter = myDots.begin(); list_iter != myDots.end(); list_iter++)
{
Dot* dot = *list_iter;
if ((dot->GetPosition() - aPosition).Length() < 5.f)
{
myDots.remove(dot);
delete dot;
return true;
}
}
return false;
}
bool World::HasIntersectedBigDot(const Vector2f& aPosition)
{
for(std::list<BigDot*>::iterator list_iter = myBigDots.begin(); list_iter != myBigDots.end(); list_iter++)
{
BigDot* dot = *list_iter;
if ((dot->GetPosition() - aPosition).Length() < 5.f)
{
myBigDots.remove(dot);
delete dot;
return true;
}
}
return false;
}
bool World::HasIntersectedCherry(const Vector2f& aPosition)
{
return true;
}
void World::GetPath(int aFromX, int aFromY, int aToX, int aToY, std::list<PathmapTile*>& aList)
{
PathmapTile* fromTile = GetTile(aFromX, aFromY);
PathmapTile* toTile = GetTile(aToX, aToY);
for(std::list<PathmapTile*>::iterator list_iter = myPathmapTiles.begin(); list_iter != myPathmapTiles.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
tile->myIsVisitedFlag = false;
}
Pathfind(fromTile, toTile, aList);
}
PathmapTile* World::GetTile(int aFromX, int aFromY)
{
for(std::list<PathmapTile*>::iterator list_iter = myPathmapTiles.begin(); list_iter != myPathmapTiles.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
if (tile->myX == aFromX && tile->myY == aFromY)
{
return tile;
}
}
return NULL;
}
bool World::ListDoesNotContain(PathmapTile* aFromTile, std::list<PathmapTile*>& aList)
{
for(std::list<PathmapTile*>::iterator list_iter = aList.begin(); list_iter != aList.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
if (tile == aFromTile)
{
return false;
}
}
return true;
}
bool SortFromGhostSpawn(PathmapTile* a, PathmapTile* b)
{
int la = abs(a->myX - 13) + abs(a->myY - 13);
int lb = abs(b->myX - 13) + abs(b->myY - 13);
return la < lb;
}
bool World::Pathfind(PathmapTile* aFromTile, PathmapTile* aToTile, std::list<PathmapTile*>& aList)
{
aFromTile->myIsVisitedFlag = true;
if (aFromTile->myIsBlockingFlag)
return false;
if (aFromTile == aToTile)
return true;
std::list<PathmapTile*> neighborList;
PathmapTile* up = GetTile(aFromTile->myX, aFromTile->myY - 1);
if (up && !up->myIsVisitedFlag && !up->myIsBlockingFlag && ListDoesNotContain(up, aList))
neighborList.push_front(up);
PathmapTile* down = GetTile(aFromTile->myX, aFromTile->myY + 1);
if (down && !down->myIsVisitedFlag && !down->myIsBlockingFlag && ListDoesNotContain(down, aList))
neighborList.push_front(down);
PathmapTile* right = GetTile(aFromTile->myX + 1, aFromTile->myY);
if (right && !right->myIsVisitedFlag && !right->myIsBlockingFlag && ListDoesNotContain(right, aList))
neighborList.push_front(right);
PathmapTile* left = GetTile(aFromTile->myX - 1, aFromTile->myY);
if (left && !left->myIsVisitedFlag && !left->myIsBlockingFlag && ListDoesNotContain(left, aList))
neighborList.push_front(left);
neighborList.sort(SortFromGhostSpawn);
for(std::list<PathmapTile*>::iterator list_iter = neighborList.begin(); list_iter != neighborList.end(); list_iter++)
{
PathmapTile* tile = *list_iter;
aList.push_back(tile);
if (Pathfind(tile, aToTile, aList))
return true;
aList.pop_back();
}
return false;
}
Snapshot:
Snapshot

Confused about Vector<type*> iterator

I have a base class cGameObject which has a virtual update function. I wish to have many derived game objects each with their own specific update function.
I want to add the derived gameobjects to a vector and iterate through them to call each of their update methods.
What is wrong with my iterator?
//In Header file
std::vector <cGameObject*> vGameObjs;
std::vector <cGameObject*>::iterator Iter;
cGameObject *AGameObj;
/In cpp file - add object pointer to vector
AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
vGameObjs.push_back(AGameObj);
AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
vGameObjs.push_back(AGameObj);
//Iterator Crashing??
for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
{
//Call Each Objects Update() method here?
}
When I run this, it throws an exception: read access violation. _Mycont was nullptr.
Not sure what to do.
error thrown
Header of Class App Class:
#ifndef _H_AGK_TEMPLATE_
#define _H_AGK_TEMPLATE_
// Link to GDK libraries
#include "AGK.h"
#include "Brickbat.h"
#include "BrickBall.h"
#include "cGameObject.h"
#include <vector>
#define DEVICE_WIDTH 1024
#define DEVICE_HEIGHT 768
#define DEVICE_POS_X 32
#define DEVICE_POS_Y 32
#define FULLSCREEN false
// used to make a more unique folder for the write path
#define COMPANY_NAME "BitMaNip:Play"
// Global values for the app
class app
{
public:
// constructor
app() { memset ( this, 0, sizeof(app)); }
// main app functions - mike to experiment with a derived class for this..
void Begin( void );
int Loop( void );
void End( void );
private:
//Vector of GameObject Pointers;
std::vector <cGameObject*> vGameObjs;
//Iterator of GameObjects
std::vector <cGameObject*>::iterator Iter;
BrickBat *MyBat;
BrickBall *MyBall;
cGameObject *AGameObj;
};
extern app App;
#endif
// Allow us to use the LoadImage function name
#ifdef LoadImage
#undef LoadImage
#endif
cpp file for Header
// Includes
#include "template.h"
#include "cGameObject.h"
#include
// Namespace
using namespace AGK;
app App;
void app::Begin(void)
{
agk::SetVirtualResolution (DEVICE_WIDTH, DEVICE_HEIGHT);
agk::SetClearColor( 151,170,204 ); // light blue
agk::SetSyncRate(60,0);
agk::SetScissor(0,0,0,0);
//Test
/*BrickBall = agk::CreateSprite(0);
agk::SetSpriteSize(BrickBall, 64, 64);
agk::SetSpriteColor(BrickBall, 255, 255, 255, 255);
xPos = (DEVICE_WIDTH - 64) / 2;
yPos = (DEVICE_HEIGHT - 64) / 2;
agk::SetSpritePosition(BrickBall, xPos , yPos );
xDir = 1;
yDir = 1;
iSpeed = 8;*/
MyBat = new BrickBat(128, 32, (1024-128)/2, 768-64, 0);
AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
vGameObjs.push_back(AGameObj);
MyBall = new BrickBall(64, 512, 384, 1, 1, 0);
AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
vGameObjs.push_back(AGameObj);
}
int app::Loop (void)
{
agk::Print( agk::ScreenFPS() );
if (agk::GetRawKeyState(37) == 1)
{
MyBat->MoveLeft();
}
if (agk::GetRawKeyState(39) == 1)
{
MyBat->MoveRight();
}
MyBat->Update();
MyBall->Update();
MyBall->Collided(MyBat->iGetBatID());
for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
{
//(*Iter)->Update();
//(*Iter)->Collided(MyBat->iGetBatID());
}
Derived class
include "cGameObject.h"
class BrickBall: public cGameObject
{
private:
bool bHoriDir;
bool bVertDir;
int iSpeed;
bool bPause; //in case game is paused
public:
BrickBall(int iSize, int xPos, int yPos, bool bHori, bool bVert, int ImageID);
virtual void Update() override;
virtual void Collided(int OtherSpriteToCheck) override;
};
agk::Sync();
return 0; // return 1 to close app
}
void app::End (void)
{
}
Base Class:
#pragma once
class cGameObject
{
protected:
bool bInit = false;
int iSprID;
int iImageID;
int iXPos;
int iYPos;
int iAngle;
int iAlpha;
int iWidth;
int iHeight;
int iColour;
//Movement
float fDeltaX;
float fDeltaY;
//Animation
int iAniType; //Type of animation
//0 = No Animation
//1 = Repeating Loop of Frames (All image is animation)
//2 =
int iFrameW; //Width of Animation Frame
int iFrameH; //Height of Animation frame
int iFPS; //Animation Delay
int iNumFrames; //Number of animation frames
int iAniCount; //Frame Counter
public:
// set up default for constructor
cGameObject(int width = 16, int height = 16, int xPos = 0, int yPos = 0, int ImageID = 0);
void SetPosition(int ixPos, int iyPos);
void SetSize(int iWidth, int iHeight);
void SetWidth(int Width);
void SetAngle(int iAngle);
void SetTransparency(int iAlpha);
void SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames);
virtual void Collided(int OtherSpriteToCheck) {};
virtual void Update() {};
int iGetWidth();
int iGetHeight();
int iGetX();
int iGetY();
int iGetSprID();
~cGameObject();
};
Base Class cpp
#include "cGameObject.h"
#include "agk.h"
void cGameObject::SetAngle(int iAngle)
{
if (bInit == true)
{
if (iAngle > 0 && iAngle < 359)
{
agk::SetSpriteAngle(iSprID, iAngle);
}
}
}
//cGameObject::cGameObject(int width, int height, int xPos, int yPos, const char * szImageFile)
cGameObject::cGameObject(int width, int height, int xPos, int yPos, int ImageID)
{
bInit = true;
iImageID = 0;
/*if (std::strlen(szImageFile) > 0)
{
iImageID = agk::LoadImage(szImageFile);
if (iImageID < 1)
{
bInit = false;
}
}*/
iColour = agk::MakeColor(255, 255, 255);
//init animation code
iAniType = 0; //Type of animation
iFrameW = 64; //Width of Animation Frame
iFrameH = 64; //Height of Animation frame
iFPS = 10; //Animation Delay
iNumFrames = 1; //Number of animation frames
iAniCount = 0; //Frame Counter
iSprID = agk::CreateSprite(iImageID);
if (iSprID < 1)
{
bInit = false;
}
else
{
agk::SetSpriteSize(iSprID, width, height);
agk::SetSpritePosition(iSprID, xPos, yPos);
fDeltaX = 4.0;
fDeltaY = 4.0;
}
}
void cGameObject::SetPosition(int ixPos, int iyPos)
{
if (bInit == true)
{
agk::SetSpritePosition(iSprID, ixPos, iyPos);
}
}
void cGameObject::SetSize(int iWidth, int iHeight)
{
if (bInit == true)
{
if (iWidth > 0 && iWidth < 1024 && iHeight > 0 && iHeight < 1024)
{
agk::SetSpriteSize(iSprID, iWidth, iHeight);
}
}
}
void cGameObject::SetWidth(int Width)
{
if (bInit == true)
{
agk::GetSpriteWidth(Width);
}
}
void cGameObject::SetTransparency(int iAlpha)
{
if (bInit == true)
{
if (iAlpha > 0 && iAlpha < 256)
{
agk::SetSpriteTransparency(iSprID, iAlpha);
}
}
}
void cGameObject::SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames)
{
//Animation
iAniType = Type;
iFrameW = FrameW; //Width of Animation Frame
iFrameH = FrameH; //Height of Animation frame
iFPS = FPS; //Animation Delay
iNumFrames = NumFrames; //Number of animation frames
iAniCount = 0; //Frame Counter
agk::SetSpriteAnimation(iSprID, iFrameW, iFrameH, iNumFrames);
if (iAniType > 0)
{
agk::PlaySprite(iSprID, iFPS);
}
}
int cGameObject::iGetWidth()
{
if (bInit == true)
{
return agk::GetSpriteWidth(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetHeight()
{
if (bInit == true)
{
return agk::GetSpriteHeight(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetX()
{
if (bInit == true)
{
return agk::GetSpriteX(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetY()
{
if (bInit == true)
{
return agk::GetSpriteY(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetSprID()
{
if (bInit == true)
{
return iSprID;
}
else
{
return 0;
}
}
cGameObject::~cGameObject()
{
if (bInit == true)
{
agk::DeleteSprite(iSprID);
}
}
Derived Class Header:
#include "cGameObject.h"
class BrickBall: public cGameObject
{
private:
bool bHoriDir;
bool bVertDir;
int iSpeed;
bool bPause; //in case game is paused
public:
BrickBall(int iSize, int xPos, int yPos, bool bHori, bool bVert, int ImageID);
virtual void Update() override;
virtual void Collided(int OtherSpriteToCheck) override;
};
Derived Class cpp
#include "BrickBall.h"
BrickBall::BrickBall(int Size, int xPos, int yPos, bool bHori, bool bVert, int ImageID):cGameObject(Size, Size, xPos, yPos, ImageID)
{
iWidth = Size;
iHeight = Size;
iXPos = xPos;
iYPos = yPos;
bHoriDir = bHori;
bVertDir = bVert;
/*iSprID = agk::CreateSprite(0);
agk::SetSpriteColor(iSprIdx, 255, 255, 255, 255);
//agk::SetSpriteSize(iSprIdx, iSize, iSize);
agk::SetSpriteSize(iSprIdx, 64, 64);
//agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
bInit = true;*/
iSpeed = 8;
}
void BrickBall::Update()
{
if (bInit==true)// && BatID > 0)
{
//Move Ball
agk::SetSpriteColor(iSprID, 100, 100, 100, 255);
agk::PrintC("BallX:");
agk::Print(iXPos);
if (bHoriDir == 1) //Right
{
iXPos = iXPos + iSpeed;
if (iXPos > 1024 - iWidth)
{
bHoriDir = 0;
}
}
else
{
iXPos = iXPos - iSpeed;
if (iXPos < 0)
{
bHoriDir = 1;
}
}
if (bVertDir == 1) //down
{
iYPos = iYPos + iSpeed;
if (iYPos > 768 - 64)
{
bVertDir = 0;
}
}
else
{
iYPos = iYPos - iSpeed;
if (iYPos < 0)
{
bVertDir = 1;
}
}
agk::SetSpritePosition(iSprID, iXPos, iYPos);
//END Move Ball
//Bat2Ball Collisions
/*if (agk::GetSpriteCollision(iSprID, BatID))
{
//We have collided.
//As Ball is bigger than the gap below the bat must have hit top or sides
//so just flip the vertcal direction
if (bVertDir == 1)
{
bVertDir = 0;
}
}*/
}
}
void BrickBall::Collided(int OtherSpriteToCheck)
{
if (agk::GetSpriteCollision(iSprID, OtherSpriteToCheck))
{
if (bVertDir == 1)
{
bVertDir = 0;
}
}
}
I don't know the cause of your error, but I got this exact error because I had an iterator to a vector, then I updated the vector, then I tried to dereference the iterator (e.g. access *myIterator). I'm new to C++, but it seems that if you alter a collection after getting an iterator for it, your iterator is no longer valid. You need to repoint your iterator to wherever it was.

Call another widget application on QPushButton

I want call another widget application calculator on pushbutton. Till this time I get success but it overlap on parent widget.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
class QLineEdit;
class QComboBox;
class calculator;
namespace Ui {
class MainWindow;
}
class MainWindow : public QWidget
{
Q_OBJECT
public:MainWindow();
public slots:
void calcButtonPressed();
private:
calculator *calc;
};
#endif // MAINWINDOW_H
and mainwindow.cpp
MainWindow::MainWindow(){
....
QPushButton *calcButton = new QPushButton(tr("Calc"));
connect(calcButton,SIGNAL(clicked(bool)),this,SLOT(calcButtonPressed()));
....
}
void MainWindow::calcButtonPressed(){
calc = new calculator(this);
calc->show();
}
calculator.cpp
#include<QtWidgets>
#include<cmath>
#include "button.h"
#include "calculator.h"
calculator::calculator(QWidget *parent): QWidget(parent)
{
sumInMemory=0.0;
sumSoFar=0.0;
factorSoFar=0.0;
waitingForOperand=true;
display=new QLineEdit("0");
display->setReadOnly(true);
display->setAlignment(Qt::AlignRight);
display->setMaxLength(15);
QFont font=display->font();
font.setPointSize(font.pointSize()+8);
display->setFont(font);
for (int i = 0; i < NumDigitButton; ++i) {
digitButton[i] = createButton(QString::number(i), SLOT(digitClicked()));
}
button *pointButton =createButton(tr("."),SLOT(pointClicked()));
button *changeSignButton=createButton(tr("\30\261"),SLOT(changeSignClicked()));
button *backspaceButton=createButton(tr("Backspace"),SLOT(backspaceClicked()));
button *clearButton=createButton(tr("Clear"),SLOT(clear()));
button *clearAllButton=createButton(tr("Clear All"),SLOT(clearAll));
button *clearMemoryButton=createButton(tr("MC"),SLOT(clearMemory()));
button *readMemoryButton=createButton(tr("MR"),SLOT(readMemory()));
button *setMemoryButton=createButton(tr("MS"),SLOT(setMemory()));
button *addToMemoryButton=createButton(tr("M+"),SLOT(addToMemory()));
button *divisionButton = createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked()));
button *timesButton = createButton(tr("\303\227"), SLOT(multiplicativeOperatorClicked()));
button *minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
button *squareRootButton = createButton(tr("Sqrt"), SLOT(unaryOperatorClicked()));
button *powerButton = createButton(tr("x\302\262"), SLOT(unaryOperatorClicked()));
button *reciprocalButton = createButton(tr("1/x"), SLOT(unaryOperatorClicked()));
button *equalButton = createButton(tr("="), SLOT(equalClicked()));
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
mainLayout->addWidget(display, 0, 0, 1, 6);
mainLayout->addWidget(backspaceButton, 1, 0, 1, 2);
mainLayout->addWidget(clearButton, 1, 2, 1, 2);
mainLayout->addWidget(clearAllButton, 1, 4, 1, 2);
mainLayout->addWidget(clearMemoryButton, 2, 0);
mainLayout->addWidget(readMemoryButton, 3, 0);
mainLayout->addWidget(setMemoryButton, 4, 0);
mainLayout->addWidget(addToMemoryButton, 5, 0);
for (int i = 1; i < NumDigitButton; ++i) {
int row = ((9 - i) / 3) + 2;
int column = ((i - 1) % 3) + 1;
mainLayout->addWidget(digitButton[i], row, column);
}
mainLayout->addWidget(digitButton[0], 5, 1);
mainLayout->addWidget(pointButton, 5, 2);
mainLayout->addWidget(changeSignButton, 5, 3);
mainLayout->addWidget(divisionButton, 2, 4);
mainLayout->addWidget(timesButton, 3, 4);
mainLayout->addWidget(minusButton, 4, 4);
mainLayout->addWidget(plusButton, 5, 4);
mainLayout->addWidget(squareRootButton, 2, 5);
mainLayout->addWidget(powerButton, 3, 5);
mainLayout->addWidget(reciprocalButton, 4, 5);
mainLayout->addWidget(equalButton, 5, 5);
setLayout(mainLayout);
setWindowTitle(tr("calculator"));
}
void calculator::digitClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
int digitValue = clickedButton->text().toInt();
if (display->text() == "0" && digitValue == 0.0)
return;
if (waitingForOperand) {
display->clear();
waitingForOperand = false;
}
display->setText(display->text() + QString::number(digitValue));
}
void calculator::unaryOperatorClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
double result = 0.0;
if (clickedOperator == tr("Sqrt")) {
if (operand < 0.0) {
abortOperation();
return;
}
result = std::sqrt(operand);
} else if (clickedOperator == tr("x\302\262")) {
result = std::pow(operand, 2.0);
} else if (clickedOperator == tr("1/x")) {
if (operand == 0.0) {
abortOperation();
return;
}
result = 1.0 / operand;
}
display->setText(QString::number(result));
waitingForOperand = true;
}
void calculator::additiveOperatorClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
return;
}
display->setText(QString::number(factorSoFar));
operand = factorSoFar;
factorSoFar = 0.0;
pendingMultiplicativeOperator.clear();
}
if (!pendingAdditiveOperator.isEmpty()) {
if (!calculate(operand, pendingAdditiveOperator)) {
abortOperation();
return;
}
display->setText(QString::number(sumSoFar));
} else {
sumSoFar = operand;
}
pendingAdditiveOperator = clickedOperator;
waitingForOperand = true;
}
void calculator::multiplicativeOperatorClicked()
{
button *clickedButton = qobject_cast<button *>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
return;
}
display->setText(QString::number(factorSoFar));
} else {
factorSoFar = operand;
}
pendingMultiplicativeOperator = clickedOperator;
waitingForOperand = true;
}
void calculator::equalClicked()
{
double operand = display->text().toDouble();
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
return;
}
operand = factorSoFar;
factorSoFar = 0.0;
pendingMultiplicativeOperator.clear();
}
if (!pendingAdditiveOperator.isEmpty()) {
if (!calculate(operand, pendingAdditiveOperator)) {
abortOperation();
return;
}
pendingAdditiveOperator.clear();
} else {
sumSoFar = operand;
}
display->setText(QString::number(sumSoFar));
sumSoFar = 0.0;
waitingForOperand = true;
}
void calculator::pointClicked()
{
if (waitingForOperand)
display->setText("0");
if (!display->text().contains('.'))
display->setText(display->text() + tr("."));
waitingForOperand = false;
}
void calculator::changeSignClicked()
{
QString text = display->text();
double value = text.toDouble();
if (value > 0.0) {
text.prepend(tr("-"));
} else if (value < 0.0) {
text.remove(0, 1);
}
display->setText(text);
}
void calculator::backspaceClicked()
{
if (waitingForOperand)
return;
QString text = display->text();
text.chop(1);
if (text.isEmpty()) {
text = "0";
waitingForOperand = true;
}
display->setText(text);
}
void calculator::clear()
{
display->setText("0");
waitingForOperand = true;
}
void calculator::clearAll()
{
sumSoFar = 0.0;
factorSoFar = 0.0;
pendingAdditiveOperator.clear();
pendingMultiplicativeOperator.clear();
display->setText("0");
waitingForOperand = true;
}
void calculator::clearMemory()
{
sumInMemory = 0.0;
}
void calculator::readMemory()
{
display->setText(QString::number(sumInMemory));
waitingForOperand = true;
}
void calculator::setMemory()
{
equalClicked();
sumInMemory = display->text().toDouble();
}
void calculator::addToMemory()
{
equalClicked();
sumInMemory += display->text().toDouble();
}
button *calculator::createButton(const QString &text, const char *member)
{
button *button1 = new button(text);
connect(button1, SIGNAL(clicked()), this, member);
return button1;
}
void calculator::abortOperation()
{
clearAll();
display->setText(tr("####"));
}
bool calculator::calculate(double rightOperand, const QString &pendingOperator)
{
if (pendingOperator == tr("+")) {
sumSoFar += rightOperand;
} else if (pendingOperator == tr("-")) {
sumSoFar -= rightOperand;
} else if (pendingOperator == tr("\303\227")) {
factorSoFar *= rightOperand;
} else if (pendingOperator == tr("\303\267")) {
if (rightOperand == 0.0)
return false;
factorSoFar /= rightOperand;
}
return true;
}
I get output as calculator overlaps on mainwindow widget.
Can I get separate window for calculator?
You must change calc = new calculator(this) to calc = new calculator().
From Qt documentation
QWidget::QWidget ( QWidget * parent = 0, Qt::WindowFlags f = 0 )
Constructs a widget which is a child of parent, with widget flags set
to f.
If parent is 0, the new widget becomes a window. If parent is another
widget, this widget becomes a child window inside parent. The new
widget is deleted when its parent is deleted.
Do not supply parent when constructing calculator, then it would become separate top-level window

SDL2 'Bullet' movement not working?

I am attempting to make a simple scrolling shooter game with SDL2. I have a moving player on a screen, and I am trying to make the player shoot a bullet using an array (so they can shoot multiple bullets) however, when I press the space bar, nothing happens, and instead the bullet image sort of flashes in the top left corner.
Heres the same code in codepad: http://codepad.org/rOhE1AqY
#include <SDL.h>
#include <stdio.h> //use for things like printf, same as cout
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
//screend dimensions& sprtie dimensions
const int SCREEN_HEIGHT = 600;
const int SCREEN_WIDTH = 400;
const int SPRITE_WIDTH = 60;
const int SPRITE_HEIGHT = 80;
const int MAX_BULLETS = 50;
SDL_Window* Window = NULL;//the window rendering to
SDL_Surface* ScreenSurface = NULL;//surface contained by window
SDL_Surface* Background = NULL;
SDL_Surface* Player = NULL;
SDL_Surface* Enemy = NULL;
SDL_Surface* Bullet = NULL;
SDL_Surface* newBullet = NULL;
SDL_Rect posPlayer, posEnemy, posBullet, posnewBullet;
const Uint8* keystate = SDL_GetKeyboardState(NULL);
SDL_Event event;
class thePlayer
{
public:
thePlayer();
void player_movement();
void show_player();
private:
};
class theBullet
{
public:
theBullet();
bool isActive;
int x_position;
int y_position;
void bullet_movement();
void add_new_bullet();
void show_bullet();
private:
};
theBullet arrayofBullets[MAX_BULLETS];
class theEnemy
{
public:
theEnemy();
void enemy_movement();
void show_enemy();
private:
};
thePlayer::thePlayer()
{
posPlayer.x = 170;
posPlayer.y = SCREEN_HEIGHT;
posPlayer.w = 20;
posPlayer.h = 30;
}
void thePlayer::player_movement()
{
if(keystate[SDL_SCANCODE_LEFT])
{
posPlayer.x -= 2;
}
if(keystate[SDL_SCANCODE_RIGHT])
{
posPlayer.x += 2;
}
if(keystate[SDL_SCANCODE_UP])
{
posPlayer.y -= 2;
}
if(keystate[SDL_SCANCODE_DOWN])
{
posPlayer.y += 2;
}
if ((posPlayer.x + SPRITE_WIDTH) > SCREEN_WIDTH)
{
posPlayer.x = (SCREEN_WIDTH - SPRITE_WIDTH);
}
if ((posPlayer.y + SPRITE_HEIGHT) > SCREEN_HEIGHT)
{
posPlayer.y = (SCREEN_HEIGHT - SPRITE_HEIGHT);
}
}
void thePlayer::show_player()
{
SDL_BlitSurface(Player, NULL, ScreenSurface, &posPlayer);
SDL_SetColorKey(Player, SDL_TRUE, SDL_MapRGB(Player->format, 255, 255, 255));
}
theBullet::theBullet()
{
/*posBullet.x;
posBullet.y;
posBullet.w = 10;
posBullet.h = 15;*/
}
void theBullet::bullet_movement()
{
/*if(keystate[SDL_SCANCODE_SPACE])
{
posBullet.x = posPlayer.x + 25;
posBullet.y = posPlayer.y + 10;
}
posBullet.y -= 2;
if(posBullet.y < 0)
{
posBullet.y = -50;
}*/
}
void theBullet::show_bullet()
{
//SDL_BlitSurface(Bullet, NULL, ScreenSurface, &posBullet);
//SDL_SetColorKey(Bullet, SDL_TRUE, SDL_MapRGB(Player->format, 255, 255, 255));//removes white background
}
theEnemy::theEnemy()
{
srand (time(NULL));
posEnemy.x = rand() % 300 + 50;
posEnemy.y =0;
posEnemy.w = 35;
posEnemy.h = 60;
}
void theEnemy::enemy_movement()
{
posEnemy.y += 1;
if(posEnemy.y > SCREEN_HEIGHT)
{
posEnemy.y = SCREEN_HEIGHT +50;
}
}
void theEnemy::show_enemy()
{
SDL_BlitSurface(Enemy, NULL, ScreenSurface, &posEnemy);
SDL_SetColorKey(Enemy, SDL_TRUE, SDL_MapRGB(Player->format, 255, 255, 255));
}
bool initialise()
{
bool success = true;
if (SDL_Init(SDL_INIT_EVERYTHING) !=0)
{
cout<<"SDL_Init Error."<<SDL_GetError()<<endl;
success = false;
}
else
{
//create the window for game
Window = SDL_CreateWindow("Scrolling Shooter Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (Window == NULL)
{
cout<<"Window Error"<<SDL_GetError()<<endl;
success = false;
}
else
{
//get window surface
ScreenSurface = SDL_GetWindowSurface(Window);
}
}
return success;
}
bool LoadingMedia()
{
bool success = true;
Background = SDL_LoadBMP("background.bmp");
if (Background == NULL)
{
cout<<"Error in loading background."<<SDL_GetError()<<endl;
success = false;
}
Player = SDL_LoadBMP("spaceship.bmp");
if (Player == NULL)
{
cout<<"Error in loading player."<<SDL_GetError()<<endl;
success = false;
}
Enemy = SDL_LoadBMP("enemy.bmp");
if (Enemy == NULL)
{
cout<<"Error in loading enemy."<<SDL_GetError()<<endl;
success = false;
}
Bullet = SDL_LoadBMP("bullet.bmp");
if (Bullet == NULL)
{
cout<<"Error in loading bullet."<<SDL_GetError()<<endl;
success = false;
}
return success;
}
void closedown()
{
SDL_FreeSurface(Background);
Background = NULL;
SDL_FreeSurface(Player);
Player = NULL;
SDL_FreeSurface(Enemy);
Enemy = NULL;
SDL_DestroyWindow(Window);
Window = NULL;
SDL_Quit();
}
int main(int argc, char** argv)
{
bool quit = false;
thePlayer myPlayer;
theEnemy myEnemy;
theBullet myBullet;
if (!initialise())
{
cout<<"Failed to initialise"<<SDL_GetError()<<endl;
}
else
{
if (!LoadingMedia())
{
cout<<"Error loading media"<<SDL_GetError()<<endl;
}
}
//makes all bullets false
for (int i=0; i<MAX_BULLETS; i++)
{
arrayofBullets[i].isActive = false;
}
//GAME LOOP
while (quit == false)
{
SDL_BlitSurface(Background, NULL, ScreenSurface, NULL);
myPlayer.show_player();
myPlayer.player_movement();
while (SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
{
quit = true;
break;
}
if(keystate[SDL_SCANCODE_SPACE])
{
for (int i=0; i<MAX_BULLETS; i++)
{
if (arrayofBullets[i].isActive == false)
{
arrayofBullets[i].x_position = posPlayer.x + 25;
arrayofBullets[i].y_position = posPlayer.y + 10;
arrayofBullets[i].isActive = true;
break;
}
}
}
//update game objects
for (int i=0; i<MAX_BULLETS; i++)
{
if (arrayofBullets[i].isActive == true)
{
arrayofBullets[i].y_position -= 2;
if (arrayofBullets[i].y_position < 0)
{
arrayofBullets[i].isActive = false;
}
}
}
for (int i=0; i<MAX_BULLETS; i++)
{
if (arrayofBullets[i].isActive == true)
{
SDL_BlitSurface(Bullet, NULL, ScreenSurface, NULL);
}
}
}
//myPlayer.show_player();
//myBullet.show_bullet();
//myEnemy.show_enemy();
//myPlayer.player_movement();
//myBullet.bullet_movement();
//myEnemy.enemy_movement();
SDL_UpdateWindowSurface(Window); //updates screen
}
closedown();
return 0;
}
SDL_BlitSurface(Bullet, NULL, ScreenSurface, NULL);
You haven't specified destination rect, so it will blit on left-top corner.
It should be
SDL_Rect dstrect;
dstrect.x = arrayofBullets[i].x_position;
dstrect.y = arrayofBullets[i].y_position;
dstrect.w = Bullet->w;
dstrect.h = Bullet->h;
SDL_BlitSurface(Bullet, NULL, ScreenSurface, &dstrect);

Form Glass Pane in LWUIT

I'm trying to make a waiting screen using Form Glass Pane in LWUIT, the following is the code that I'm using
public class LoadingGlassPane implements Painter {
public static boolean isShown = false;
public static IForm form;
public void paint(Graphics g, Rectangle rect) {
System.out.println("paint LoadingGlassPane");
Font font = g.getFont();
int color = g.getColor();
g.setColor(0);
g.setFont(Font.getDefaultFont());
g.drawString("Loading...", 20, 120);
g.setColor(color);
g.setFont(font);
}
public void installPane(IForm f) {
f.setGlassPane(this);
}
public void uninstallPane(IForm f) {
f.setGlassPane(null);
}
public static IForm getForm() {
return form;
}
public static void setForm(IForm form) {
LoadingGlassPane.form = form;
}
public static boolean isIsShown() {
return isShown;
}
public static void setIsShown(boolean isShown) {
LoadingGlassPane.isShown = isShown;
}
}
and
public class ProgressGlassPane extends LoadingGlassPane implements Animation, Runnable {
int spacing = 20;
int fontSpacing = 10;
String loadMsg = "Loading...";
//HTMLComponent htmlC;
// Dialog loading;
// public ProgressGlassPane(Dialog loading) {
// this.loading = loading;
// }
public ProgressGlassPane() {
}
public void paint(Graphics g, Rectangle rect) {
//while (isShown == true) {
System.out.println("paint ProgressGlassPane");
int color = g.getColor();
Font font = g.getFont();
int pos = (int) ((System.currentTimeMillis() % 2700) / 300);
Font f = Font.getDefaultFont();
//int startX = loading.getAbsoluteX() + (loading.getWidth() / 2) - spacing;
int startX = (LGB.width / 2) - spacing;
//int fontStartX = loading.getAbsoluteX() + (loading.getWidth() - f.stringWidth(loadMsg)) / 2;
int fontStartX = (LGB.width - f.stringWidth(loadMsg)) / 2;
//int startY = loading.getAbsoluteY() + (loading.getHeight() / 2) - spacing - (f.getHeight() + fontSpacing) / 2;
int startY = (LGB.height / 2) - spacing - (f.getHeight() + fontSpacing) / 2;
int i = 0;
g.setColor(0xffffff);
g.fillRect(Math.min(startX - 3, fontStartX), startY - 3, Math.max(spacing * 2 + 7, f.stringWidth(loadMsg)) + 1, spacing * 2 + 7 + f.getHeight() + fontSpacing);
g.setColor(0);
g.setFont(f);
g.drawString(loadMsg, fontStartX, startY);
startY += f.getHeight() + fontSpacing;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
int thickness = 3;
if (i == pos) {
thickness = 7;
} else if (i == pos - 1) {
thickness = 5;
}
g.fillRect(startX + x * spacing - (thickness / 2), startY + y * spacing - (thickness / 2), thickness, thickness);
i++;
}
}
g.setColor(color);
g.setFont(font);
// }
}
public boolean animate() {
return true;
}
public void paint(Graphics g) {
paint(g, null);
}
//void installPane(Form f) {
public void installPane(IForm f) {
super.installPane(f);
//f.setGlassPane(this);
f.registerAnimated(this);
}
//void uninstallPane(Form f) {
public void uninstallPane(IForm f) {
super.uninstallPane(f);
//f.setGlassPane(this);
f.deregisterAnimated(this);
}
public void run() {
System.out.println("I'm running");
if (isShown == true && form != null) {
installPane(form);
}
else
{
uninstallPane(form);
}
}
}
and from within my form
public static ProgressGlassPane progressPane;
progressPane = new ProgressGlassPane();
progressPane.setForm(this);
progressPane.setIsShown(true);
progressPane.run();
//Some Webservice code I want to run
progressPane.setIsShown(false);
What I want to do exactly is to open the glass pan while I'm loading my data and hide it when I finish, but what Happen it send the request and after get the response show the glass pane , I have tried to put my glass pane in different thread to run independently from the main thread, and it is also not working.
Is the webservice code blocking?
If you are on the EDT then that just wouldn't work. You need to uninstall from the completion.