I'm trying to make it where the character is in a tile and when they move up or down it moves to the next tile but I'm not sure how to do that. Right now, I have it set up where the character moves by pixels but I want it to move by 1 square.
The code right now is this, and it works, but it's glitchy in pixel mode. I believe if it was by blocks it might work better but I might change it anyway.
float spritewidth = sprite->stretchX;
float spriteheight = sprite->stretchY;
float bushwidth = bush->stretchX;
float bushheight = bush->stretchY;
//Basic border collision
if (sprite->x <= 0)
sprite->x = 0;
if (sprite->y <= 0)
sprite->y = 0;
if (sprite->x >= 455)
sprite->x = 455;
if (sprite->y >= 237)
sprite->y = 237;
if ( (sprite->x + spritewidth > bush->x) && (sprite->x < bush->x + bushwidth) && (sprite->y + spriteheight > bush->y) && (sprite->y < bush->y + bushheight) )
{
bushcol = 1;
}
else
{
bushcol = 0;
}
if (osl_keys->held.down)
{
if (bushcol == 1)
{
sprite->y = bush->y - spriteheight - 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->y += 3;
}
}
if (osl_keys->held.up)
{
if (bushcol == 1)
{
sprite->y = bush->y + bushheight + 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->y -= 3;
}
}
if (osl_keys->held.right)
{
if (bushcol == 1)
{
sprite->x = bush->x - spritewidth - 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->x += 3;}
}
if (osl_keys->held.left)
{
if (bushcol == 1)
{
sprite->x = bush->x + bushwidth + 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->x -= 3;
}
}
If you want the character to move one tile/square/block at a time, just move the sprite the number of pixels the tile is wide (or tall).
const int tile_width = 32; // or something
// and then
sprite->x += tile_width;
Related
The other day, I wrote a console game of Tic-Tac-Toe in c++ for my son. He wanted me to add a computer, and I ended us using the minimax algorithm for the first time. I did some quick testing, but really just gave my laptop to my son as soon as it was printing stuff, who played with it for a couple minuets. I looked over his sholder once or twice, and noticed that it wasn't playing optimally, iv'e been trying to debug it, but I can't see where it goes wrong. I tried getting rid of alpha beta prunning, but that did not change anything.
For context, on the board the computer is -1, blank is 0, and the player is 1.
Here is the minimax function:
int minimax(int board[9], int depth, int alpha, int beta, bool isMaxizimaizingPlayer)
{
bool found = false;
for (int i = 0; i < 9; i++)
{
if (board[i] == 0)
{
found = true;
}
}
if (!found)
{
return eval(board);
}
if (depth == 0 || eval(board) != 0)
{
return eval(board);
}
if (isMaxizimaizingPlayer)
{
int maxEval = -2;
for (int spot = 0; spot < 9; spot++)
{
if (board[spot] == 0)
{
board[spot] = 1;
int e = minimax(board, depth - 1, alpha, beta, false);
if (e > maxEval)
{
maxEval = e;
}
//if (beta < alpha)
//{
// break;
//}
board[spot] = 0;
}
}
return maxEval;
}
else {
int minEval = 2;
for (int spot = 0; spot < 9; spot++)
{
if (board[spot] == 0)
{
board[spot] = -1;
int e = minimax(board, depth - 1, alpha, beta, true);
if (e < minEval)
{
minEval = e;
}
//if (beta < alpha)
//{
// break;
//}
board[spot] = 0;
}
}
return minEval;
}
}
To be compleate, here is my eval function:
int eval(int board[9])
{
/*horizontial*/
for (int i = 0; i < 3; i++)
{
if (board[i * 3] == board[i * 3 + 1] && board[i * 3 + 2] == board[i * 3] && board[i * 3] != 0)
{
return board[i * 3];
}
}
/*vertical*/
for (int i = 0; i < 3; i++)
{
if (board[i] == board[i + 3] && board[i] == board[i + 6] && board[i] != 0)
{
return board[i];
}
}
/*Both diags*/
if (board[4] != 0) {
if (board[0] == board[4] && board[0] == board[8])
{
return board[4];
}
if (board[2] == board[4] && board[4] == board[6])
{
return board[4];
}
}
return 0;
}
And here is the inital call:
int spot = 0;
int minEval = 2;
for (int i = 0; i < 9; i++)
{
if (board[i] == 0)
{
board[i] = -1;
int score = minimax(board, 3, -2, 2, false);
if (score < minEval) {
minEval = score;
spot = i;
}
board[i] = 0;
}
}
std::cout << "The computer went in spot " << spot + 1 << std::endl;
board[spot] = -1;
printBoard(board);
It looks like you only call minimax with a depth of three, so the algorithm will only look up to three moves ahead, if you want optimal play you need to set the depth to > 9, so that the agent is always looking ahead to the end of the game.
I'm currently trying to write a menu function for one of my projects. I'm remaking pac-man and I'd like to be able to modularize the main menu, calling it when I want it to appear. I'm thinking an SDL_surface and a TTF font are all I need as parameters for this particular function.
I ran into trouble when I used SDL functions only available in SDL 1.2 as opposed to 2.0. I would like this code to be as reusable as possible. How would you guys approach this problem? I have some sample code below, though not all of it is my own. I'd like to get something like this working:
int showmenu(SDL_Surface* screen, TTF_Font* font)
{
Uint32 time;
int x, y;
const int NUMMENU = 2;
const char* labels[NUMMENU] = {"Continue","Exit"};
SDL_Surface* menus[NUMMENU];
bool selected[NUMMENU] = {0,0};
SDL_Color color[2] = {{255,255,255},{255,0,0}};
menus[0] = TTF_RenderText_Solid(font,labels[0],color[0]);
menus[1] = TTF_RenderText_Solid(font,labels[1],color[0]);
SDL_Rect pos[NUMMENU];
pos[0].x = screen->clip_rect.w/2 - menus[0]->clip_rect.w/2;
pos[0].y = screen->clip_rect.h/2 - menus[0]->clip_rect.h;
pos[1].x = screen->clip_rect.w/2 - menus[0]->clip_rect.w/2;
pos[1].y = screen->clip_rect.h/2 + menus[0]->clip_rect.h;
SDL_FillRect(screen,&screen>clip_rect,SDL_MapRGB(screen>format,0x00,0x00,0x00));
SDL_Event event;
while(1)
{
time = SDL_GetTicks();
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
SDL_FreeSurface(menus[0]);
SDL_FreeSurface(menus[1]);
return 1;
case SDL_MOUSEMOTION:
x = event.motion.x;
y = event.motion.y;
for(int i = 0; i < NUMMENU; i += 1)
{
if(x >= pos[i].x && x <= pos[i].x + pos[i].w &&
y >= pos[i].y && y <= pos[i].y + pos[i].h)
{
if(!selected[i])
{
selected[i] = 1;
SDL_FreeSurface(menus[i]);
menus[i] = TTF_RenderText_Solid(font,labels[i],color[1]);
}
}
else
{
if(selected[i])
{
selected[i] = 0;
SDL_FreeSurface(menus[i]);
menus[i] = TTF_RenderText_Solid(font,labels[i],color[0]);
}
}
}
break;
case SDL_MOUSEBUTTONDOWN:
x = event.button.x;
y = event.button.y;
for(int i = 0; i < NUMMENU; i += 1)
{
if(x >= pos[i].x && x <= pos[i].x + pos[i].w &&
y >= pos[i].y && y <= pos[i].y + pos[i].h)
{
SDL_FreeSurface(menus[0]);
SDL_FreeSurface(menus[1]);
return i;
}
}
break;
case SDL_KEYDOWN:
if(event.key.keysym.sym == SDLK_ESCAPE)
{
SDL_FreeSurface(menus[0]);
SDL_FreeSurface(menus[1]);
return 0;
}
}
}
for(int i = 0; i < NUMMENU; i += 1)
{
SDL_BlitSurface(menus[i],NULL,screen,&pos[i]);
}
}
}
I'm fighting with this for like few days, and I have no idea, how to do that, so I'd like to ask you for help. I've got no idea how collision should look like right here, so player could jump through 'down zone' of the block, and stay right on the block.
block.cpp
bool block::CollidingWithPlayer(character& player) {
for (int i = 1; i < MAX_BLOCKS; i++) {
if (player.x + player.width >= coordinateX[i] && player.x <= coordinateX[i] + width[i] && player.y + player.height >= coordinateY[i] && player.y <= coordinateY[i] + block_height) {
player.onGround = true;
return true;
}
}
}
character.cpp
void character::startJump(map& Map, character& player) {
if (onGround)
{
vel[1] = -11.0;
onGround = false;
}
}
void character::updateJump(block& Block, character& player) {
if (!onGround) {
Block.CollidingWithPlayer(player);
vel[1] += 0.5;
y += vel[1];
x += vel[0];
}
if (y > 460){
y = 460;
vel[1] = 0.0;
onGround = true;
vel[0] = 0.0;
}
if ((x + width >= START_OF_RIGHT_WALL && x <= WALL_WIDTH + START_OF_RIGHT_WALL) || (x + width >= START_OF_LEFT_WALL &&x <= START_OF_LEFT_WALL + WALL_WIDTH)){
vel[0] *= -1;
bound = true;
if (direction == 1)
direction = 2;
else if (direction == 2)
direction = 1;
}
}
I want to draw a circle. but anything isn't drawn.
for (int i = 0; i < 1080; i += 3) {
angle = (float)M_PI / 180.0f * i;
vertices[i] = sinf((float)angle) * 0.5f;
vertices[i + 1] = cosf((float)angle) * 0.5f;
vertices[i + 2] = 0.0f;
}
bool isFirst = true;
int temp;
for (int i = 0, j = 1; i < 360; i++) {
if (i % 3 == 0) {
indices[i] = 0;
}
else {
if (!isFirst) {
temp = ++j;
isFirst = true;
}
else {
temp = j;
isFirst = false;
}
indices[i] = (GLushort)temp;
}
}
.
.
.
glDrawElements(GL_TRIANGLE_STRIP, 360, GL_UNSIGNED_SHORT, 0);
Please help me......
first code works fine on android java gl es2.0.
for (int i = 0; i < 1080; i += 3) {
angle = (float)M_PI / 180.0f * i;
vertices[i] = sinf((float)angle) * 0.5f;
vertices[i + 1] = cosf((float)angle) * 0.5f;
vertices[i + 2] = 0.25f;
}
bool isFirst = true;
int temp;
for (int i = 0, j = 1; i < 360; i++) {
if (i % 3 == 0) {
indices[i] = 0;
}
else {
if (!isFirst) {
temp = ++j;
isFirst = true;
}
else {
temp = j;
isFirst = false;
}
indices[i] = (GLushort)temp;
}
}
I have multiple SDL_Rects creating a snake that is supposed to stay in a specific area. Sometimes when the "snake" reaches the boundaries a part disappears.
void Snake::update(SDL_Surface *screen, int level)
{
old_pos.first = snake_rect[0];
if(x_axis)
snake_rect[0].x += snake_speed * level * direction_multiplier;
else if(!x_axis)
snake_rect[0].y += snake_speed * level * direction_multiplier;
for(unsigned int i = 1; i < snake_rect.size(); ++i)
{
old_pos.second = snake_rect[i];
snake_rect[i] = old_pos.first;
old_pos.first = old_pos.second;
}
boundariesCheck(screen);
/// Making the enemy move randomly
if(rand() % 100 < 10)
{
if(x_axis)
{
x_axis = false;
direction.second = rand() % 2;
if(direction.second)
direction_multiplier = 1;
else if(!direction.second)
direction_multiplier = -1;
}
else if(!x_axis)
{
x_axis = true;
direction.first = rand() % 2;
if(direction.first)
direction_multiplier = 1;
else if(!direction.first)
direction_multiplier = -1;
}
}
}
void Snake::draw(SDL_Surface *screen)
{
for(unsigned int i = 1; i < snake_rect.size(); ++i)
{
SDL_FillRect(screen, &snake_rect[i], 0xFF0000);
}
SDL_FillRect(screen, &snake_rect[0], 0xFF5500);
}