SDL2 segfaults on key press - c

My program segfaults as soon as I press a key, but I am unable to come up with a minimal code. If I comment out pixels[y][pdpix] = col[sampleX][sampleY]; (line 110), key presses work as normal. Otherwise, it segfaults.
Full code and "bmp" files: https://drive.google.com/file/d/1663hiKbvodcNu0xG8FpbYACAUoGScfAn/view?usp=sharing
Code in main.c:
#include <SDL2/SDL.h>
#include <stdbool.h>
#include "read.h"
#define RESX 960
#define RESY 540
#define HRESX 480
#define DRAWDISTANCE 360
#define ROTSPEED 0.005
#define BGCOL 0
#define ARESY 539
void main() {
readCW();
bool running = true;
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
running = false;
}
window = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, RESX, RESY, SDL_WINDOW_SHOWN );
if( window==NULL) {
printf( "SDL_Error: %s\n", SDL_GetError() );
running = false;
}
renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED);
if(renderer==NULL) {
printf("Renderer error: %s\n", SDL_GetError() );
running = false;
}
SDL_Texture * texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, RESX,RESY);
readBW();
float playerX = 512;
float playerY = 512;
float dirX = 0.0;
float dirY = 1.0;
void rotatez(float rotspeed) {
float oldDirX = dirX;
dirX = dirX * cos(rotspeed) - dirY * sin(rotspeed);
dirY = oldDirX * sin(rotspeed) + dirY * cos(rotspeed);
}
const Uint8* keystate = SDL_GetKeyboardState( NULL );
while( running ) {
clock_t t1, t2;
t1 = SDL_GetTicks();
Uint32 pixels[RESY][RESX] = {[0 ... RESY-1][0 ...RESX-1] = 0x5555FF};
SDL_Event e;
running = !(SDL_PollEvent( &e ) && e.type == SDL_QUIT);
if(keystate[SDL_SCANCODE_ESCAPE]) running = false;
if(keystate[SDL_SCANCODE_LEFT]) rotatez(-ROTSPEED);
if(keystate[SDL_SCANCODE_RIGHT]) rotatez(ROTSPEED);
if(keystate[SDL_SCANCODE_W]) {
playerY += dirY;
playerX += dirX;
}
if(keystate[SDL_SCANCODE_S]) {
playerY -= dirY;
playerX -= dirX;
}
if(keystate[SDL_SCANCODE_A]) {
playerY -= dirX;
playerX += dirY;
}
if(keystate[SDL_SCANCODE_D]) {
playerY += dirX;
playerX -= dirY;
}
//rotatez(-ROTSPEED);
playerY -= dirY;//for testing
playerX -= dirX;//for testing
int heightBuffer[RESX] = {[0 ... 959] = RESY};
int playerHeight = 80;//disp[(int)playerX][(int)playerY] + 50;
int dpix = 0;
for( int dDist = 1; dDist < DRAWDISTANCE; dDist+=1) {
for( int pix = -dDist; pix < dDist; pix++) {
int pdpix = dpix;
dpix = (pix/(float)dDist+1) *HRESX;
int sampleX = (int)playerX + dDist*dirX + pix*-dirY;
int sampleY = (int)playerY + dDist*dirY + pix*dirX;
int height = disp[sampleX][sampleY];
int heightOnScreen = ( ((float)playerHeight - height) / dDist * 240 + 240); //alg for persp proj
if(heightOnScreen > 0 && heightOnScreen < RESY) {
for( pdpix; pdpix < dpix; pdpix++) {
if(heightOnScreen < heightBuffer[pdpix]) {
for(int y = heightBuffer[pdpix]; y > heightOnScreen; y-=1) {
pixels[y][pdpix] = col[sampleX][sampleY]; //if I comment out this line, segfault goes away.
}
heightBuffer[pdpix] = heightOnScreen;
}
}
}
}
}
SDL_UpdateTexture(texture, NULL, pixels, RESX * sizeof(Uint32));
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent( renderer );
t2 = SDL_GetTicks();
printf("%ld fps\n", 1000/(t2-t1));
}
SDL_DestroyWindow( window );
SDL_DestroyRenderer( renderer );
SDL_DestroyTexture( texture );
SDL_Quit();
}

Related

SDL2 Camera Cutting Off Screen Edges

I'm trying to create a simple camera for my SDL2 platformer with C. However, whenever the player reaches the screen edges, it seems to be cut off by the background. Here is what the player looks like normally:
And here is what the player looks like when it reaches the screen edges:
To make the camera follow the player, I'm just creating a SDL_Rect called camera, setting it to the player x and y positions, and setting the viewport with SDL_RenderSetViewport to the camera rectangle.
Here's the code for that:
void handle_camera() {
SDL_Rect camera = {
.x = WIDTH/2 - player.x - BLOCK_SIZE/2,
.y = HEIGHT/2 - player.y - BLOCK_SIZE/2,
.w = WIDTH,
.h = HEIGHT
};
SDL_RenderSetViewport(game.renderer, &camera);
}
Therefore, I was wondering: what's wrong with my camera function and why is the player being cut off when it gets near the screen edges?
Here is the full code if needed (I organized in functions so I hope it's not too hard to understand):
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#define WIDTH 1200
#define HEIGHT 800
#define BLOCK_SIZE 50
#define PLATFORM_AMOUNT 11 //This makes sure there are enough iterations of the loop, and also allocates enough memory for the 2D array of platforms.
#define LAVA_AMOUNT 2
#define TRAMPOLINE_AMOUNT 1
//Prototyping Functions
int initialize();
void handle_input();
void draw_player();
void player_moveX();
void player_moveY();
void checkCollisionsX();
void checkCollisionsY();
int rectCollide();
void drawLevel();
void resetPlayer();
void handle_camera();
typedef struct {
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Surface *surface;
bool running;
int FPS;
bool close_requested;
int input[256];
} Game;
Game game = {
.running = true,
.FPS = 80,
.close_requested = false,
.input = {},
};
typedef struct {
int x;
int y;
double x_vel;
double y_vel;
double x_acc;
double y_acc;
int width;
int height;
double accSpeed;
int maxVel;
double gravity;
double friction;
double jumpForce;
double canJump;
} Player;
Player player = {
.y = HEIGHT-(BLOCK_SIZE*2),
.x = BLOCK_SIZE,
.x_vel = 0,
.y_vel = 0,
.x_acc = 0,
.y_acc = 0,
.width = BLOCK_SIZE,
.height = BLOCK_SIZE,
.accSpeed = 0.15,
.maxVel = 7,
.gravity = 0.5,
.friction = 0.15,
.jumpForce = 15,
.canJump = true,
};
int platforms[PLATFORM_AMOUNT][4] = {
{0, 0, BLOCK_SIZE, HEIGHT}, //WALLS
{0, HEIGHT-BLOCK_SIZE, WIDTH, BLOCK_SIZE},
{400-BLOCK_SIZE, HEIGHT-(BLOCK_SIZE*2), BLOCK_SIZE, BLOCK_SIZE}, //RAMP TO LAVA
{400-BLOCK_SIZE, HEIGHT-(BLOCK_SIZE*3), BLOCK_SIZE, BLOCK_SIZE},
{300, HEIGHT-(BLOCK_SIZE*2), BLOCK_SIZE, BLOCK_SIZE},
{800, HEIGHT-(BLOCK_SIZE*2), BLOCK_SIZE, BLOCK_SIZE},
{800, HEIGHT-(BLOCK_SIZE*3), BLOCK_SIZE, BLOCK_SIZE},
{800+BLOCK_SIZE, HEIGHT-(BLOCK_SIZE*2), BLOCK_SIZE, BLOCK_SIZE},
{WIDTH-BLOCK_SIZE*10, HEIGHT-(BLOCK_SIZE*8), BLOCK_SIZE, BLOCK_SIZE}, //Blocks above lava
{WIDTH-BLOCK_SIZE*8, HEIGHT-(BLOCK_SIZE*10), BLOCK_SIZE, BLOCK_SIZE},
{BLOCK_SIZE, BLOCK_SIZE*3, BLOCK_SIZE*9, BLOCK_SIZE}, //Top platform
};
int lava[LAVA_AMOUNT][4] = {
{400, HEIGHT-(BLOCK_SIZE*3), 400, BLOCK_SIZE*2},
{BLOCK_SIZE*4, BLOCK_SIZE*2, BLOCK_SIZE*3, BLOCK_SIZE},
};
int trampoline[TRAMPOLINE_AMOUNT][4] = {
{WIDTH/2-(BLOCK_SIZE/2), HEIGHT-(BLOCK_SIZE*5), BLOCK_SIZE, BLOCK_SIZE}
};
int main() {
initialize();
while(game.running && !game.close_requested) { //Game loop
SDL_SetRenderDrawColor(game.renderer, 181, 247, 255, 255);
SDL_RenderClear(game.renderer);
handle_input();
handle_camera();
//Collisions only work in this order: playerMoveX, checkCollisionsX, playerMoveY, checkCollisionsY. Then you can draw the platforms and the player.
player_moveX();
checkCollisionsX();
player_moveY();
checkCollisionsY();
drawLevel();
draw_player();
SDL_RenderPresent(game.renderer);
SDL_Delay(1000/game.FPS);
} //End of game loop
SDL_DestroyRenderer(game.renderer);
SDL_DestroyWindow(game.window);
SDL_Quit();
return 0;
}
int initialize() {
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) { //return 0 on success
printf("error initializing SDL: %s\n", SDL_GetError());
return 1;
}
game.window = SDL_CreateWindow("Sam's Platformer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_RESIZABLE); //creates window
if (!game.window) {
printf("error creating window: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
Uint32 render_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; //creates a renderer
game.renderer = SDL_CreateRenderer(game.window, -1, render_flags);
if (!game.renderer) {
printf("error creating renderer: %s\n", SDL_GetError());
SDL_DestroyWindow(game.window);
SDL_Quit();
return 1;
}
return 0;
}
void handle_input() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
game.close_requested = true;
game.running = false;
}
//printf("input: %p code: %i\n", game.input, event.key.keysym.scancode);
if (event.type == SDL_KEYDOWN) {
game.input[event.key.keysym.scancode] = true;
//printf("True");
}
if (event.type == SDL_KEYUP) {
game.input[event.key.keysym.scancode] = false;
//printf("False");
}
}
if (game.input[SDL_SCANCODE_R]) {
resetPlayer();
}
}
void draw_player() {
SDL_Rect playerRect = {
.x = player.x,
.y = player.y,
.w = player.width,
.h = player.height
};
SDL_SetRenderDrawColor(game.renderer, 0, 200, 50, 255);
SDL_RenderFillRect(game.renderer, &playerRect);
}
void resetPlayer() {
player.y = HEIGHT-(BLOCK_SIZE*2);
player.x = BLOCK_SIZE;
player.x_vel = 0;
player.y_vel = 0;
}
void player_moveX() {
if (game.input[SDL_SCANCODE_LEFT] && player.x_vel > -player.maxVel) {
player.x_acc = -player.accSpeed;
} else if (game.input[SDL_SCANCODE_RIGHT] && player.x_vel < player.maxVel) {
player.x_acc = player.accSpeed;
} else if (abs(player.x_vel) > 0.2) {
if (player.x_vel < 0) {
player.x_acc = player.friction;
} else {
player.x_acc = -player.friction;
}
} else {
player.x_vel = 0;
player.x_acc = 0;
}
player.x_vel += player.x_acc;
player.x += player.x_vel;
}
void player_moveY() {
if (game.input[SDL_SCANCODE_UP] && player.y_vel == 0 && player.y_acc == 0 && player.canJump) {
player.canJump = false;
player.y_vel = -player.jumpForce;
}
player.y_acc += player.gravity;
player.y_vel += player.y_acc;
player.y += player.y_vel;
player.y_acc = 0;
}
void checkCollisionsX() {
for (int i = 0; i < PLATFORM_AMOUNT; i++) {
if (rectCollide(player.x, player.y, BLOCK_SIZE, BLOCK_SIZE, platforms[i][0], platforms[i][1], platforms[i][2], platforms[i][3])) {
if (player.x_vel < 0) { // If the player moved left and collided with the right side of block
player.x = platforms[i][0] + platforms[i][2];
} else { // If the player moved right and collided with the left side of block
player.x = platforms[i][0] - player.width;
}
player.x_vel = 0;
}
}
/*if (player.x >= WIDTH - player.width) {
player.x = WIDTH - player.width;
player.x_vel = 0;
}*/
for (int i = 0; i < LAVA_AMOUNT; i++) {
if (rectCollide(player.x, player.y, BLOCK_SIZE, BLOCK_SIZE, lava[i][0], lava[i][1], lava[i][2], lava[i][3])) {
resetPlayer();
}
}
for (int i = 0; i < TRAMPOLINE_AMOUNT; i++) {
if (rectCollide(player.x, player.y, BLOCK_SIZE, BLOCK_SIZE, trampoline[i][0], trampoline[i][1], trampoline[i][2], trampoline[i][3])) {
if (player.x_vel < 0) { // If the player moved left and collided with the right side of block
player.x = trampoline[i][0] + trampoline[i][2];
} else { // If the player moved right and collided with the left side of block
player.x = trampoline[i][0] - player.width;
}
player.x_vel = 0;
}
}
}
void checkCollisionsY() {
for (int i = 0; i < PLATFORM_AMOUNT; i++) {
if (rectCollide(player.x, player.y, player.width, player.height, platforms[i][0], platforms[i][1], platforms[i][2], platforms[i][3])) {
if (player.y_vel < 0) { // If the player hit their head
player.y = platforms[i][1] + platforms[i][3];
player.y_vel *= -0.5; // Not -1 because collisions are not perfectly elastic
} else {
player.y = platforms[i][1] - player.height;
player.y_vel = 0;
player.y_acc = 0;
player.canJump = true;
}
}
if (player.y >= HEIGHT - player.height) {
player.y_vel = 0;
player.y = HEIGHT - player.height;
if (!game.input[SDL_SCANCODE_UP]) {
player.canJump = true;
}
}
}
for (int i = 0; i < LAVA_AMOUNT; i++) {
if (rectCollide(player.x, player.y, BLOCK_SIZE, BLOCK_SIZE, lava[i][0], lava[i][1], lava[i][2], lava[i][3])) {
resetPlayer();
}
}
for (int i = 0; i < TRAMPOLINE_AMOUNT; i++) {
if (rectCollide(player.x, player.y, BLOCK_SIZE, BLOCK_SIZE, trampoline[i][0], trampoline[i][1], trampoline[i][2], trampoline[i][3])) {
if (player.y_vel < 0) { // If the player hit their head
player.y = trampoline[i][1] + trampoline[i][3];
player.y_vel *= -0.5; // Not -1 because collisions are not perfectly elastic
} else {
player.y = trampoline[i][1] - trampoline[i][3];
player.y_vel = -player.y_vel;
}
}
}
}
int rectCollide(int x1, int y1, int w1, int h1, int x2,int y2, int w2, int h2) {
return x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2;
}
void drawLevel() {
for (int i = 0; i < PLATFORM_AMOUNT; i++) {
SDL_Rect platform = {platforms[i][0], platforms[i][1], platforms[i][2], platforms[i][3]};
SDL_SetRenderDrawColor(game.renderer, 156, 104, 0, 255);
SDL_RenderFillRect(game.renderer, &platform);
}
for (int i = 0; i < LAVA_AMOUNT; i++) {
int lavaRedColor = 255;
SDL_Rect lavaBlock = {lava[i][0], lava[i][1], lava[i][2], lava[i][3]};
SDL_SetRenderDrawColor(game.renderer, lavaRedColor, 0, 0, 255);
SDL_RenderFillRect(game.renderer, &lavaBlock);
}
for (int i = 0; i < TRAMPOLINE_AMOUNT; i++) {
SDL_Rect trampolineBlock = {trampoline[i][0], trampoline[i][1], trampoline[i][2], trampoline[i][3]};
SDL_SetRenderDrawColor(game.renderer, 235, 52, 229, 255);
SDL_RenderFillRect(game.renderer, &trampolineBlock);
}
}
void handle_camera() {
SDL_Rect camera = {
.x = WIDTH/2 - player.x - BLOCK_SIZE/2,
.y = HEIGHT/2 - player.y - BLOCK_SIZE/2,
.w = WIDTH, //Screen width
.h = HEIGHT //Screen height
};
SDL_RenderSetViewport(game.renderer, &camera);
}
Thanks for any help.
https://gamedev.stackexchange.com/questions/121421/how-to-use-the-sdl-viewport-properly
See this related post. Essentially changing the SDL viewport is not the way you'd typically handle an in game camera. You need to consider drawing your in game entities (level objects etc.) relative to the camera.

Why does this SDL2 program slow down?

I have a problem with this program that reads audio data from an input device and displays a line representing the volume level. It starts ok then a few seconds later it starts lagging. It worked without slow downs until I tried to add some code to add image display functionality, which didn't work so I removed it, but now it the program doesn't work properly. I've removed most of the program functionality which I'll add back if I fix it. The CPU and GPU usage remains low so no problems there. If I switch to Software Mode it seems to work. I'm on Windows using MinGW-w64.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <math.h>
int SCREEN_WIDTH = 1024; //default
int SCREEN_HEIGHT = 768; //default
int FULLSCREEN = 0;
SDL_Renderer *rend;
//#define SOFTWARE_RENDER
//#define VSYNC_ON
#define PROGRAM_NAME "My Game"
#ifdef SOFTWARE_RENDER
#define RENDERER SDL_RENDERER_SOFTWARE
#else
#define RENDERER SDL_RENDERER_ACCELERATED
#endif
#if !defined(SOFTWARE_RENDER) && defined(VSYNC_ON)
#define VSYNC SDL_RENDERER_PRESENTVSYNC
#else
#define VSYNC 0
#endif
////https://wiki.libsdl.org/SDL_AudioSpec#callback
void audioInCallback(void *userdata, Uint8 *stream,int len)
{
float *floatStream = (float*)stream;
if (stream == NULL)
{
puts("Stream is NULL.");
return;
}
SDL_SetRenderDrawColor(rend, 0, 0, 0, 255);
SDL_RenderClear(rend);
SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
float avg = 0;
for (int i=0;i<len;i++)
avg += fabs(floatStream[i]);
avg /= len;
SDL_RenderDrawLine(rend, 0,
SCREEN_HEIGHT/2 + round(SCREEN_HEIGHT/2.0 * avg),
SCREEN_WIDTH,
SCREEN_HEIGHT/2 + round(SCREEN_HEIGHT/2.0 * avg)
);
return;
}
int main(int argv, char *argc[])
{
int bufferSize = 8;
SDL_Window* window = NULL;
rend = NULL;
SDL_Event event;
bool loopIsActive = true;
SDL_AudioSpec want, have;
SDL_AudioDeviceID dev;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
{
printf("Unable to initialize SDL: %s", SDL_GetError());
return 1;
}
if( (window = SDL_CreateWindow( PROGRAM_NAME, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
SCREEN_HEIGHT, SDL_WINDOW_SHOWN )) == NULL )
{
printf("Window could not be created! %s\n", SDL_GetError());
SDL_Quit();
return 0;
}
if ( (rend = SDL_CreateRenderer(window, -1, RENDERER | VSYNC)) == NULL )
{
printf("Error creating renderer. %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
int count = SDL_GetNumAudioDevices(1);
for (int i=0;i<count;i++)
{
printf("%d. %s\n", i, SDL_GetAudioDeviceName(i, 1));
}
SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
want.freq = 44100;
want.format = AUDIO_S16;
want.channels = 1;
want.samples = pow(2,bufferSize);
want.callback = audioInCallback;
dev = SDL_OpenAudioDevice(NULL, 1, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
if (dev == 0)
printf("Failed to open audio: %s", SDL_GetError());
else
{
printf("have.samples = %u\n", have.samples);
printf("Opened device %s\nAudio format: ", SDL_GetAudioDeviceName(0, 1));
if (SDL_AUDIO_ISFLOAT(have.format))
printf("%d-bit %s\n", SDL_AUDIO_BITSIZE(have.format), SDL_AUDIO_ISFLOAT(have.format) ? "float" :
SDL_AUDIO_ISSIGNED(have.format) ? "signed" : "unsigned");
SDL_PauseAudioDevice(dev, 0); /* start audio playing. */
}
while (loopIsActive == true)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
loopIsActive = false;
break;
case SDL_KEYDOWN:
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
loopIsActive = false;
}
break;
}
}
SDL_RenderPresent(rend);
SDL_Delay(16);
}
if (dev != 0) SDL_CloseAudioDevice(dev);
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window);
SDL_Quit();
puts("Hello world!");
return 0;
}
Don't try to do SDL_Renderer operations in a different thread like the one the audio callback is typically called from. As #keltar pointed out this is prohibited by SDL:
These functions must be called from the main thread.
Instead, bundle up the audio samples via your favorite method for rendering on the main thread (sorry for the C++, not much of a C guy re: threading primitives):
#include <SDL.h>
#include <vector>
#include <atomic>
#include <iostream>
// triple-buffering logic stol^H^H^H^Hborrowed from:
// https://stackoverflow.com/questions/49352853
std::vector< float >* g_ProducerBuffer;
std::vector< float >* g_ConsumerBuffer;
std::atomic< std::vector< float >* > g_CurrentBuffer;
void audioInCallback( void* userdata, Uint8* stream, int len )
{
const float* floatStream = reinterpret_cast< float* >( stream );
for( auto& sample : *g_ProducerBuffer )
{
sample = *floatStream;
floatStream++;
}
// post new buffer
g_ProducerBuffer = g_CurrentBuffer.exchange( g_ProducerBuffer );
}
int main( int argc, char** argv )
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" );
//SDL_SetHint( SDL_HINT_RENDER_DRIVER, "software" );
Uint32 flags = SDL_WINDOW_SHOWN;
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_CreateWindowAndRenderer( 1024, 768, flags, &window, &renderer );
// dump device names
int count = SDL_GetNumAudioDevices( 1 );
for( int i = 0; i < count; i++ )
{
std::cout << i << ": " << SDL_GetAudioDeviceName( i, 1 ) << '\n';
}
SDL_AudioSpec spec = { 0 };
spec.freq = 44100;
spec.format = AUDIO_F32LSB;
spec.channels = 1;
spec.samples = 1024;
spec.callback = audioInCallback;
const unsigned int deviceIndex = 0;
const std::string deviceName = SDL_GetAudioDeviceName( deviceIndex, 1 );
SDL_AudioDeviceID dev = SDL_OpenAudioDevice( deviceName.c_str(), 1, &spec, nullptr, 0 );
// set up audio buffers
std::vector< float > buffers[ 3 ];
buffers[ 0 ].resize( spec.samples );
buffers[ 1 ].resize( spec.samples );
buffers[ 2 ].resize( spec.samples );
g_ProducerBuffer = &buffers[ 0 ];
g_ConsumerBuffer = &buffers[ 1 ];
g_CurrentBuffer = &buffers[ 2 ];
// start audio capture
SDL_PauseAudioDevice( dev, 0 );
bool running = true;
while( running )
{
SDL_Event ev;
while( running && SDL_PollEvent( &ev ) )
{
if( SDL_QUIT == ev.type ||
SDL_KEYDOWN == ev.type && SDL_SCANCODE_ESCAPE == ev.key.keysym.scancode )
{
running = false;
}
}
SDL_SetRenderDrawColor( renderer, 0, 0, 0, 255 );
SDL_RenderClear( renderer );
// grab latest audio buffer
// (this *seems* to work on my system but I'm not 100% sure it's correct)
while( !g_CurrentBuffer.compare_exchange_weak( g_ConsumerBuffer, g_ConsumerBuffer ) );
// draw audio sample waveform
std::vector< SDL_Point > points( g_ConsumerBuffer->size() );
for( size_t i = 0; i < g_ConsumerBuffer->size(); ++i )
{
const int x = static_cast< int >( i );
const int y = static_cast< int >( (*g_ConsumerBuffer)[ i ] * 200 + 768 / 2 );
points[ i ] = SDL_Point{ x, y };
}
SDL_SetRenderDrawColor( renderer, 255, 255, 255, 255 );
SDL_RenderDrawLines( renderer, points.data(), points.size() );
SDL_RenderPresent( renderer );
}
SDL_CloseAudioDevice( dev );
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}

My code won't display sprite SDL2

The screen is always black. Tell me how to display the sprites correctly.
This is my code:
#define SHAPE_SIZE 32
void aff_map(SDL_Renderer *renderer)
{
SDL_Surface *img;
SDL_Texture *Tfloor
int x = 0;
int y = 0;
int map[4][8] = {{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
SDL_Rect SrcR;
SDL_Rect DestR;
DestR.x = 0;
DestR.y = 0;
DestR.w = SHAPE_SIZE;
DestR.h = SHAPE_SIZE;
img = IMG_Load("floor.bmp");
Tfloor = SDL_CreateTextureFromSurface(renderer, img);
while (y < 4)
{
x = 0;
while (x < 8)
{
if (map[y][x] == 0)
SDL_RenderCopy(renderer, Tfloor, NULL, &DestR);
x++;
DestR.x = DestR.x + 32;
}
DestR.x = 0;
DestR.y = DestR.y + 32;
y++;
}
SDL_RenderPresent(renderer);
}
int main()
{
SDL_Window *screen;
SDL_Event evenements;
SDL_Renderer *renderer;
screen = SDL_CreateWindow("Zappy", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 8 * SHAPE_SIZE -32, 4 * SHAPE_SIZE, 0);
renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderClear(renderer);
while (42)
{
SDL_WaitEvent(&evenements);
if (evenements.window.event == SDL_WINDOWEVENT_CLOSE ||
evenements.key.keysym.sym == SDLK_ESCAPE)
{
SDL_DestroyWindow(screen);
SDL_Quit();
break;
}
aff_map(renderer);
}
return 0;
}
The error message is explicit.
It says that the "floor.bmp" has not been converted to a surface.
It means that 'img' parameter is NULL.
Try the following :
Specify the full path to your picture in IMG_Load(), for example "/home/quentin/floor.bmp"
Check the return value of IMG_Load().

camshift object tracking problems

i have developed camshift algorithm by watching some tutorials..but unfortunately it didn't track the selected object....here is my code..i am a beginner to opencv and i need help..problem is the rectangle doesn't follow the object to track...
this my code:
bool destroy=false;
CvRect box;
CvRect track_window;
bool drawing_box = false;
cv::Mat imageROI;
IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0, *backproject = 0, *histimg = 0;
CvHistogram *hist = 0;
int hdims = 16;
float hranges_arr[] = {0,180};
float* hranges = hranges_arr;
int vmin = 10, vmax = 256, smin = 30;
IplImage *image2;
CvScalar hsv2rgb( float hue );
CvConnectedComp track_comp;
CvBox2D track_box;
void draw_box(Mat img, CvRect rect)
{
imageROI= img(cv::Rect(box.x,box.y,box.width,box.height));
cv::rectangle(img, cvPoint(box.x, box.y), cvPoint(box.x+box.width,box.y+box.height),
cvScalar(0,0,255) ,2);
}
CvScalar hsv2rgb( float hue )
{
int rgb[3], p, sector;
static const int sector_data[][3]=
{{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};
hue *= 0.033333333333333333333333333333333f;
sector = cvFloor(hue);
p = cvRound(255*(hue - sector));
p ^= sector & 1 ? 255 : 0;
rgb[sector_data[sector][0]] = 255;
rgb[sector_data[sector][1]] = 0;
rgb[sector_data[sector][2]] = p;
return cvScalar(rgb[2], rgb[1], rgb[0],0);
}
void my_mouse_callback( int event, int x, int y, int flags, void* param )
{
IplImage* frame = (IplImage*) param;
switch( event )
{
case CV_EVENT_MOUSEMOVE:
{
if( drawing_box )
{
box.width = x-box.x;
box.height = y-box.y;
}
}
break;
case CV_EVENT_LBUTTONDOWN:
{
drawing_box = true;
box = cvRect( x, y, 0, 0 );
}
break;
case CV_EVENT_LBUTTONUP:
{
drawing_box = false;
if( box.width < 0 )
{
box.x += box.width;
box.width *= -1;
}
if( box.height < 0 )
{
box.y += box.height;
box.height *= -1;
}
draw_box(frame, box);
}
break;
case CV_EVENT_RBUTTONUP:
{
destroy=true;
}
break;
default:
break;
} }
int _tmain(int argc, _TCHAR* argv[])
{
VideoCapture cap(0);
if(!cap.isOpened())
return -1;
Mat image;
Mat frame;
//cv::Mat image= cv::imread("1.jpg");
cap>>image;
if (!image.data)
return 0;
// Display image
cv::namedWindow("Image");
cv::imshow("Image",image);
IplImage* img = new IplImage(image);
cvSmooth(img,img,CV_GAUSSIAN,3,0,0.0,0.0);
IplImage* temp = cvCloneImage(img);
cvSetMouseCallback("Image", my_mouse_callback, (void*) img);
while( 1 )
{
if (destroy)
{
cvDestroyWindow("Image"); break;
}
cvCopyImage(img, temp);
if (drawing_box)
draw_box(temp, box);
cvShowImage("Image", temp);
if (cvWaitKey(15) == 27)
break;
}
cvReleaseImage(&temp);
cvDestroyWindow("Image");
for(;;)
{
int i, bin_w, c;
cap >> frame;
IplImage* frame_ipl = new IplImage(frame);
hsv = cvCreateImage( cvGetSize(frame_ipl), 8, 3 );
image2 = cvCreateImage( cvGetSize(frame_ipl), 8, 3 );
hue = cvCreateImage( cvGetSize(frame_ipl), 8, 1 );
mask = cvCreateImage( cvGetSize(frame_ipl), 8, 1 );
backproject = cvCreateImage( cvGetSize(frame_ipl), 8, 1 );
hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 );
histimg = cvCreateImage( cvSize(320,200), 8, 3 );
cvZero( histimg );
cvCopy( frame_ipl, image2, 0 );
cvCvtColor( image2, hsv, CV_BGR2HSV );
int _vmin = vmin, _vmax = vmax;
cvInRangeS( hsv, cvScalar(0,smin,MIN(_vmin,_vmax),0),
cvScalar(180,256,MAX(_vmin,_vmax),0), mask );
cvSplit( hsv, hue, 0, 0, 0 );
float max_val = 0.f;
cvSetImageROI( hue, box );
cvSetImageROI( mask, box );
cvCalcHist( &hue, hist, 0, mask );
cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 );
cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );
cvResetImageROI( hue );
cvResetImageROI( mask );
track_window = box;
cvZero( histimg );
bin_w = histimg->width / hdims;
for( i = 0; i < hdims; i++ )
{
int val = cvRound( cvGetReal1D(hist->bins,i)*histimg->height/255 );
CvScalar color = hsv2rgb(i*180.f/hdims);
cvRectangle( histimg, cvPoint(i*bin_w,histimg->height),
cvPoint((i+1)*bin_w,histimg->height - val),
color, -1, 8, 0 );
}
cvCalcBackProject( &hue, backproject, hist );
cvAnd( backproject, mask, backproject, 0 );
cvCamShift( backproject, track_window, cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ), &track_comp, &track_box );
track_window = track_comp.rect;
cv::rectangle(frame, track_window, cv::Scalar(0,255,0));
cv::namedWindow("result");
cv::imshow("result",frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
but I use the c-api
What might this code be changed to IplImage :
void draw_box(Mat img, CvRect rect)
{
imageROI= img(cv::Rect(box.x,box.y,box.width,box.height));
cv::rectangle(img, cvPoint(box.x, box.y), cvPoint(box.x+box.width,box.y+box.height),
cvScalar(0,0,255) ,2);
}

Program built using Unity3D Freezing PC - Sporadic

My program that I built using Unity3D sporadically freezes, and this action freezes my computer. I'm unable to pinpoint the root cause. I had placed logs all over my project, but the game failed to freeze.
Has any Unity3D developer experience their apps sporadically freeze in the manner in which I am describing? Does anyone have any ideas or suggestions?
Due to a 30K character limit, the below object has been modified slightly. This is the object I believe contains a flaw, but I am unable to identify this flaw.
public class gamePlayController : MonoBehaviour {
void Start () {
int i = 0;
int selectedPlayers = PlayerPrefs.GetInt("TotalPlayers");
foreach( GameObject touchable in GameObject.FindGameObjectsWithTag("Touchable") )
{
touchable.SetActive(false);
touchable.AddComponent(typeof(PlayerCollisionDispatcher));
PlayerCollisionDispatcher nextDispatcher = touchable.GetComponent<PlayerCollisionDispatcher>();
nextDispatcher.currentGameObject = touchable;
nextDispatcher.gameObject.AddComponent("AudioSource");
for(i = 0; i < this.m_Players.Count; i++)
{
if(string.Compare(touchable.name, this.m_Players[i].name) < 0)
{
break;
}
}
if(i < this.m_Players.Count)
{
this.m_Players.Insert(i, touchable);
}
else
{
this.m_Players.Add(touchable);
}
}
while(this.m_Players.Count > selectedPlayers)
{
this.m_Players.RemoveRange(selectedPlayers, this.m_Players.Count - selectedPlayers);
}
this.restartGame();
}
void OnGameTimer(object sender, ElapsedEventArgs e)
{
}
void Update() {
Vector3 vector = m_ArialCamera.camera.transform.position;
vector.x = Mathf.Abs((1500 * this.m_ArialView.x) - 1500) + 250;
vector.y = (600 * this.m_ArialView.y) + 100;
vector.z = (1500 * this.m_ArialView.z) + 250;
m_ArialCamera.camera.transform.position = vector;
if(this.m_IsGameOver)
{
Application.LoadLevel("Replay Screen");
}
else if(this.m_SimulateCamera)
{
this.SimulateCamera();
}
else if(m_AutoPluck)
{
this.AutoPluck();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher && this.m_Dispatcher.didObjectStop)
{
this.determineTurnOutcome();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher && this.m_Dispatcher.didObjectMove)
{
this.m_Dispatcher.trackMovementProgress();
}
else if(Time.timeScale != 0.0f && this.m_Dispatcher
&& this.m_Players[this.m_PlayerIndex].rigidbody.velocity.magnitude > 15.0f
&& this.m_Dispatcher.didPluck)
{
this.m_Dispatcher.didObjectMove = true;
}
}
void restartGame()
{
this.m_PlayerIndex = -1;
foreach( GameObject touchable in this.m_Players)
{
GameObject startField = GameObject.FindWithTag ("StartField");
touchable.SetActive(false);
touchable.rigidbody.useGravity = false;
touchable.rigidbody.velocity = Vector3.zero;
touchable.rigidbody.AddForce(Vector3.zero);
touchable.rigidbody.AddTorque(Vector3.zero);
if(startField)
{
Vector3 nextPoint = startField.renderer.bounds.center;
nextPoint.y = 11.0f;
touchable.transform.position = nextPoint;
}
touchable.rigidbody.useGravity = true;
}
this.startNextPlayer();
}
void startNextPlayer()
{
bool isActivePlayerReady = true;
do{
if(this.m_PlayerIndex != -1)
{
audioPlayer.PlayAudio("Audio/Next Player");
}
this.m_PlayerIndex = (this.m_PlayerIndex + 1)%this.m_Players.Count;
this.m_Dispatcher = this.m_Players[this.m_PlayerIndex].GetComponent<PlayerCollisionDispatcher>();
if(this.m_Dispatcher && !this.m_Dispatcher.isGameOver && !this.m_Dispatcher.didEnterMud)
{
if(!this.m_Players[this.m_PlayerIndex].activeSelf)
{
this.m_Dispatcher.startGame();
this.m_Players[this.m_PlayerIndex].SetActive(true);
}
this.m_Dispatcher.startTurn();
}
}
while(!isActivePlayerReady);
Vector3 vector = this.m_Players[this.m_PlayerIndex].transform.position;
vector.x = (1500 * this.m_ArialView.x) + 250;
vector.y = 300;
vector.z = (1500 * this.m_ArialView.z) + 250;
m_ArialCamera.camera.transform.position = vector;
this.setAnnouncement("Player " + this.m_Players[this.m_PlayerIndex].name + "'s Turn");
if(this.m_PlayerIndex != 0)
{
this.m_IsSimulating = PlayerPrefs.GetInt("SimulatePlayer" + this.m_Players[this.m_PlayerIndex].name);
this.m_IsSimulating = 1;
}
else
{
this.m_IsSimulating = 0;
}
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
}
if(this.m_IsSimulating >= 1)
{
this.StartSimulation();
if(mo)
{
mo.DoFreeze = true;
}
}
else
{
if(mo)
{
mo.DoFreeze = false;
}
}
}
void StartSimulation()
{
System.Random random = new System.Random();
StringBuilder sb = new StringBuilder();
int randomNumber = 0;
//determine either the player object or the next block
if(this.m_Dispatcher.isKiller)
{
m_SimulateToObject = this.m_Players[randomNumber%this.m_Players.Count];
randomNumber = random.Next(0, 100);
}
else
{
sb.AppendFormat("{0:D2}", this.m_Dispatcher.targetScore);
Debug.Log("target score=" + sb.ToString());
foreach(GameObject scoreField in GameObject.FindGameObjectsWithTag("ScoreField"))
{
if(scoreField.name == sb.ToString())
{
m_SimulateToObject = scoreField;
break;
}
}
}
this.m_IsTargetInitiallyVisible = false;
this.m_SimulationTimer = new System.Timers.Timer();
this.m_SimulationTimer.Elapsed+=new ElapsedEventHandler(TriggerCameraSimulation);
this.m_SimulationTimer.Interval=2500;
this.m_SimulationTimer.Enabled=true;
}
void TriggerCameraSimulation(object sender, ElapsedEventArgs e)
{
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
this.m_SimulateCamera = true;
}
void SimulateCamera()
{
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
if(!this.m_IsTargetInitiallyVisible)
{
mo.IsManualMove = true;
mainCamera.transform.position = this.m_Players[this.m_PlayerIndex].transform.position;
mainCamera.transform.LookAt(this.m_SimulateToObject.transform, Vector3.up);
this.m_IsTargetInitiallyVisible = true;
}
else if(this.m_SimulateCamera)
{
if(mo.getDistance() >= 10.0f)
{
this.m_SimulateCamera = false;
}
mo.setDistance(-0.001f);
}
}
if(!this.m_SimulateCamera)
{
this.m_SimulationTimer = new System.Timers.Timer();
this.m_SimulationTimer.Elapsed+=new ElapsedEventHandler(TriggerSimulatedPluck);
this.m_SimulationTimer.Interval=2000;
this.m_SimulationTimer.Enabled=true;
}
}
void TriggerSimulatedPluck(object sender, ElapsedEventArgs e)
{
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
this.m_AutoPluck = true;
}
void AutoPluck()
{
System.Random random = new System.Random();
GameObject mainCamera = GameObject.FindWithTag ("MainCamera");
MouseOrbit mo = null;
float applyForce = 0.0f;
float slope = 0.00028648399272739457f;
float y_int = 0.2908366193449838f;
Vector3 vTorque = Vector3.zero;
int simulateId = PlayerPrefs.GetInt("SimulatePlayer" + this.m_Players[this.m_PlayerIndex].name);
int seed = (5 * ((int)(SimulationOptions.Pro) - simulateId));
int xSeed = 0;
int ySeed = 0;
int zSeed = 0;
int sign = random.Next(1, 1000)%2;
int range = random.Next(1, 1000)%seed;
int myValue = 0;
this.m_SimulationTimer.Enabled = false;
this.m_SimulationTimer.Dispose();
if(mainCamera)
{
mo = mainCamera.GetComponent<MouseOrbit>();
mo.IsManualMove = false;
}
this.m_AutoPluck = false;
if(simulateId >= 1)
{
float distance = Vector3.Distance(this.m_Players[this.m_PlayerIndex].transform.position,
this.m_SimulateToObject.transform.position);
if(simulateId != (int)(SimulationOptions.Pro))
{
myValue = random.Next(1, 6);
seed = (int)(myValue * ((int)(SimulationOptions.Pro) - simulateId));
sign = random.Next(1, 2);
range = random.Next(1, seed);
if(random.Next(1, 1000)%3 == 0)
{
distance += (sign == 1 ? range : -range);
}
}
vTorque.x = (float)(random.Next(1, 90));
vTorque.y = (float)(random.Next(1, 90));
vTorque.z = (float)(random.Next(1, 90));
applyForce = (slope * distance) + y_int;
this.m_Dispatcher.pluckObject(applyForce, vTorque);
}
}
void determineTurnOutcome()
{
int number = -1;
bool canActivePlayerContinue = false;
bool isAutoReward = false;
bool didElinimatePlayer = false;
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
if(nextObject.activeSelf && !nextDispatcher.isGameOver && !nextDispatcher.isActive)
{
if(nextDispatcher.currentScore == nextDispatcher.targetScore)
{
nextDispatcher.totalScore = nextDispatcher.targetScore;
int.TryParse(nextDispatcher.name, out number);
nextDispatcher.targetScore++;
if(nextDispatcher.totalScore >= 13 || nextDispatcher.targetScore > 13)
{
nextDispatcher.totalScore = 13;
nextDispatcher.targetScore = 13;
nextDispatcher.isKiller = true;
this.setMaterial(nextDispatcher.renderer, "killers", nextDispatcher.name);
}
else
{
this.setMaterial(nextDispatcher.renderer, "numbers", nextDispatcher.name);
}
}
else if(nextDispatcher.didKillerCollide && (nextDispatcher.didLeaveBoard || nextDispatcher.didLeaveBounds))
{
this.setMaterial(nextDispatcher.renderer, "eliminated", nextDispatcher.name);
nextDispatcher.isGameOver = true;
didElinimatePlayer = true;
}
else if(nextDispatcher.didPlayerCollide && (nextDispatcher.didLeaveBoard || nextDispatcher.didLeaveBounds))
{
if(int.TryParse(nextDispatcher.name, out number))
{
nextDispatcher.targetScore = 1;
nextDispatcher.totalScore = 0;
}
}
else if(nextDispatcher.didEnterMud)
{
this.setMaterial(nextDispatcher.renderer, "mudd", nextDispatcher.name);
nextDispatcher.isKiller = false;
}
else if(nextDispatcher.isInMud && !nextDispatcher.didEnterMud)
{
isAutoReward = true;
}
else
{
this.setMaterial(nextDispatcher.renderer, "numbers", nextDispatcher.name);
}
}
nextDispatcher.transferStates();
}
if(this.m_Dispatcher.isKiller && !didElinimatePlayer)
{
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
this.m_Dispatcher.totalScore = 0;
this.m_Dispatcher.targetScore = 1;
this.m_Dispatcher.isKiller = false;
}
else if(this.m_Dispatcher.didEnterMud)
{
this.setMaterial(this.m_Dispatcher.renderer, "mud", this.m_Dispatcher.name);
}
else if(this.m_Dispatcher.currentScore == this.m_Dispatcher.targetScore || isAutoReward)
{
this.m_Dispatcher.totalScore = this.m_Dispatcher.targetScore;
canActivePlayerContinue = true;
this.m_Dispatcher.consecutivePops++;
int.TryParse(this.m_Dispatcher.name, out number);
this.m_Dispatcher.targetScore++;
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
}
else
{
this.setMaterial(this.m_Dispatcher.renderer, "numbers", this.m_Dispatcher.name);
}
this.isWinnerAnnounced();
if(!this.m_IsGameOver && !canActivePlayerContinue)
{
this.m_Dispatcher.endTurn();
this.startNextPlayer();
}
else if(canActivePlayerContinue)
{
this.m_Dispatcher.transferStates();
this.m_Dispatcher.isActive = true;
this.m_Dispatcher.didObjectMove = false;
this.m_Dispatcher.didObjectStop = false;
if(this.m_IsSimulating >= 1)
{
this.StartSimulation();
}
}
this.m_ForceValue = 0.0f;
}
void isWinnerAnnounced()
{
StringBuilder sb = new StringBuilder();
int totalPlayers = 0;
string winner = string.Empty;
int number = -1;
int totalPlayersInMud = 0;
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
if(!nextDispatcher.isGameOver)
{
totalPlayers++;
winner = nextObject.name;
}
if(nextDispatcher.isInMud)
{
totalPlayersInMud++;
}
}
if(totalPlayers == 1)
{
if(winner != string.Empty && int.TryParse(winner, out number))
{
sb.AppendFormat("Congratulations Player {0}", number);
PlayerPrefs.SetString("WinningPlayer", sb.ToString());
}
else
{
PlayerPrefs.SetString("WinningPlayer", "Congratulations");
}
this.m_IsGameOver = true;
}
else if(totalPlayersInMud == this.m_Players.Count)
{
PlayerPrefs.SetString("WinningPlayer", "All players are stuck in the mud!");
this.m_IsGameOver = true;
}
}
void setMaterial(Renderer renderer, string state, string playerId)
{
StringBuilder sbNextImage = new StringBuilder();
sbNextImage.AppendFormat("Materials/playerObjects/{0}/{1}", state, playerId);
Material newMat = Resources.Load(sbNextImage.ToString(), typeof(Material)) as Material;
if(newMat)
{
renderer.material = newMat;
}
else
{
Debug.Log("FAILED to set material: " + sbNextImage.ToString());
}
}
void setAnnouncement(string text)
{
this.m_IsAnnouncement = true;
this.m_AnnouncementHeight = (int)(Screen.height * 0.5);
this.m_AnnouncementText = text;
}
void OnGUI() {
GUIStyle labelStyle = GUI.skin.label;
int number = -1;
StringBuilder scoreDetails = new StringBuilder();
StringBuilder turnDetails = new StringBuilder();
float x = 0;
float y = 0;
float w = 64.0f;
float h = 32.0f;
float alpha = 1.0f;
if(this.m_IsAnnouncement)
{
this.displayAnnouncement();
}
labelStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
Texture2D texture = new Texture2D(32, 32, TextureFormat.ARGB32, false);
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
texture.SetPixel(i, j, new Color(0.0f, 0.0f, 0.0f, 0.25f));
}
}
texture.Apply();
labelStyle.normal.background = texture;
if(this.m_DoShowScore)
{
foreach(GameObject nextObject in this.m_Players)
{
PlayerCollisionDispatcher nextDispatcher = nextObject.GetComponent<PlayerCollisionDispatcher>();
int.TryParse(nextDispatcher.name, out number);
if(nextDispatcher.isGameOver)
{
scoreDetails.AppendFormat("\tPlayer {0}: Game Over\n", number);
}
else if(nextDispatcher.didEnterMud)
{
scoreDetails.AppendFormat("\tPlayer {0}: In The Mudd\n", number);
}
else if(nextDispatcher.isKiller)
{
scoreDetails.AppendFormat("\tPlayer {0}: Killer\n", number);
}
else
{
scoreDetails.AppendFormat("\tPlayer {0}: {1}\n", number, nextDispatcher.totalScore);
}
}
GUI.Label (new Rect (0, 0, 225, 100), scoreDetails.ToString());
}
w = 64.0f;
h = 32.0f;
x = Screen.width - w;
y = Screen.height - h;
if(GUI.Button (new Rect (x, y, w, h), "Menu"))
{
audioPlayer.PlayAudio("Audio/Click");
this.m_IsMenuShowing = !this.m_IsMenuShowing;
}
if(this.m_IsMenuShowing)
{
w = (64.0f * this.m_MenuText.Length);
h = 32.0f;
x = Screen.width - w - 64.0f;
y = Screen.height - h;
int selOption = GUI.Toolbar(new Rect(x, y, w, h), this.m_MenuOption, this.m_MenuText);
if(selOption != this.m_MenuOption)
{
audioPlayer.PlayAudio("Audio/Click");
this.m_MenuOption = -1;
this.m_IsMenuShowing = !this.m_IsMenuShowing;
switch(selOption)
{
case (int)(MenuOptions.ArialViewOption): //arial
this.m_ArialCamera.SetActive(!this.m_ArialCamera.activeSelf);
break;
case (int)(MenuOptions.VolumeOption): //mute
int muteVolume = PlayerPrefs.GetInt("MuteVolume");
muteVolume = (muteVolume + 1)%2;
PlayerPrefs.SetInt("MuteVolume", muteVolume);
if(muteVolume == 0)
{
this.m_MenuText[(int)(MenuOptions.VolumeOption)] = "Mute";
}
else
{
this.m_MenuText[(int)(MenuOptions.VolumeOption)] = "Volume";
}
break;
case (int)(MenuOptions.PauseOption): //pause
if(Time.timeScale == 0.0f)
{
this.setAnnouncement("Continuing Game Play");
Time.timeScale = this.m_Speed;
this.m_MenuText[(int)(MenuOptions.PauseOption)] = "Pause";
}
else
{
this.setAnnouncement("Game Is Paused");
Time.timeScale = 0.0f;
this.m_MenuText[(int)(MenuOptions.PauseOption)] = "Play";
}
break;
case (int)(MenuOptions.ScoresOption): //scores
this.m_DoShowScore = !this.m_DoShowScore;
break;
case (int)(MenuOptions.RestartOption): //restart
Time.timeScale = this.m_Speed;
this.restartGame();
break;
case (int)(MenuOptions.QuitOption): //quit
Application.LoadLevel("Opening Screen");
break;
default:
break;
}
}
}
if(this.m_ArialCamera.activeSelf)
{
x = Screen.width * 0.7f - 10.0f;
y = 0;
w = 10.0f;
h = Screen.height * 0.3f;
this.m_ArialView.z = GUI.VerticalSlider (new Rect(x, y, w, h), this.m_ArialView.z, 1.0f, 0.0f);
x = Screen.width * 0.7f;
y = Screen.height * 0.3f;
w = Screen.width * 0.3f;
h = 10.0f;
this.m_ArialView.x = GUI.HorizontalSlider (new Rect(x, y, w, h), this.m_ArialView.x, 1.0f, 0.0f);
x = Screen.width * 0.7f;
y = Screen.height * 0.3f + 12.0f;
w = Screen.width * 0.3f;
h = 10.0f;
this.m_ArialView.y = GUI.HorizontalSlider (new Rect(x, y, w, h), this.m_ArialView.y, 1.0f, 0.0f);
}
int.TryParse(this.m_Players[this.m_PlayerIndex].name, out number);
turnDetails.AppendFormat("\tPlayer {0}'s Turn\n", number);
turnDetails.AppendFormat("\tNext Goal: {0}\n", this.m_Dispatcher.targetScore);
GUI.Label (new Rect (0, Screen.height - 100, 225, 100), turnDetails.ToString());
if(!this.m_Dispatcher.didObjectMove && m_IsSimulating == 0)
{
x = 250.0f;
y = Screen.height - 190.0f;
w = 30.0f;
h = 150.0f;
this.m_ForceValue = GUI.VerticalSlider (new Rect(x, y, w, h), m_ForceValue, 1.0f, 0.0f);
x = 250.0f;
y = Screen.height - 30.0f;
w = 100.0f;
h = 30.0f;
if(GUI.Button (new Rect(x, y, w, h), "Pluck!"))
{
System.Random random = new System.Random();
Vector3 vTorque = Vector3.zero;
int xSeed = 0;
int ySeed = 0;
int zSeed = 0;
xSeed = (random.Next(1, 45));
ySeed = (random.Next(1, 45));
zSeed = (random.Next(1, 45));
vTorque = new Vector3(xSeed, ySeed, zSeed);
this.m_Dispatcher.pluckObject(this.m_ForceValue, vTorque);
}
}
}
void displayAnnouncement()
{
float x = 0;
float y = 0;
float w = 0;
float h = 0;
float alpha = 1.0f;
GUIStyle announcementStyle = null;
GUIStyle labelStyle = null;
announcementStyle = new GUIStyle();
labelStyle = GUI.skin.label;
labelStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
x = (int)(Screen.width * 0.25);
y = (int)m_AnnouncementHeight;
w = (int)(Screen.width * 0.5);
h = 100;
alpha = (float)m_AnnouncementHeight/(float)(Screen.height * 0.5);
announcementStyle.fontSize = 32;
announcementStyle.alignment = TextAnchor.MiddleCenter;
announcementStyle.fontStyle = FontStyle.BoldAndItalic;
announcementStyle.normal.textColor = new Color(1.0f, 1.0f, 1.0f, alpha);
GUI.Label (new Rect (x, y, w, h), this.m_AnnouncementText, announcementStyle);
if(Time.timeScale != 0.0f)
{
if((this.m_AnnouncementHeight + h) <= 0)
{
this.m_IsAnnouncement = false;
this.m_AnnouncementHeight = (int)(Screen.height * 0.5);
}
else
{
this.m_AnnouncementHeight -= 1;
}
}
}
}
-----------
I believe I have narrowed the freezing down. Simulated testing results is leading me to believe that my problem is inside the OnGUI() method. I have commented that method out all together, and my app is operating smoothly. I'll figure this out, unless someone beats me to the root cause and solution.
I solved it...
My initial suspicions were correct: the problem did lie within the OnGUI() method. I moved the following source code to the Start() method. It made sense, since I'm only building a transparent background texture once.:
Texture2D texture = new Texture2D(32, 32, TextureFormat.ARGB32, false);
for(int i = 0; i < 32; i++)
{
for(int j = 0; j < 32; j++)
{
texture.SetPixel(i, j, new Color(0.0f, 0.0f, 0.0f, 0.25f));
}
}
texture.Apply();

Resources