• Advertisement

werdy666

Member
  • Content count

    86
  • Joined

  • Last visited

Community Reputation

743 Good

About werdy666

  • Rank
    Member

Personal Information

  • Interests
    Art
    Design
    Programming
  1. Learning GameStates

    Thanks for the link L. Spiro. I will catch up on some reading and learning!   I will check out your source code too Irlan :)
  2. Learning GameStates

    Hi,   I'm looking at using game states in my programming So I went looking and found Lazy Foo's tutorial on states. I found I could understand it even though I still don't like pointers!   Here is a small program I have made to learn how to use game states. I understand if I want to know the history of what state I have been in I could use a stack, At this stage I don't need a stack to keep track of each state. my games are not big enough yet.   Here is some code int main() { GameState *CurrentState = NULL; CurrentState = new Title(); bool ExitGame = false; while (ExitGame == false) { CurrentState->ProcessEvents(); CurrentState->Update(); CurrentState->Render(); if(CurrentState->GetNextState() != -1) { if (CurrentState->GetNextState() == GameStates::ExitScreen) { delete CurrentState; ExitGame = true; } else if (CurrentState->GetNextState() == GameStates::SplashScreen) { delete CurrentState; CurrentState = new Splash(); } else if (CurrentState->GetNextState() == GameStates::TitleScreen) { delete CurrentState; CurrentState = new Title(); } else if (CurrentState->GetNextState() == GameStates::HighScoreScreen) { delete CurrentState; CurrentState = new HighScores(); } } } return 0; } And here is one of the states.... Title.H #pragma once #include "GameState.h" #include "SFML/Graphics.hpp" #include <iostream> class Title : public GameState { public: Title(); void ProcessEvents(); void Update(); void Render(); ~Title(); }; Title::Title() { std::cout << "Title" << std::endl; m_NextState = -1; } void Title::Update() { } void Title::ProcessEvents() { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { m_NextState = GameStates::ExitScreen; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { m_NextState = GameStates::SplashScreen; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::H)) { m_NextState = GameStates::HighScoreScreen; } } void Title::Render() { } Title::~Title() { } This is the first time I have used the virtual keyword in C++.   This is my base gamestate class. #pragma once enum GameStates { NullGamestate, SplashScreen, TitleScreen, HighScoreScreen, ExitScreen }; class GameState { public: virtual void Update(); virtual void ProcessEvents(); virtual void Render(); int GetNextState(); virtual ~GameState(); int m_NextState; }; My question is this.   Am I using this correctly? In a way I look at it like each state, like TitleScreen, Highscores etc is its own program. It could be one state is Pacman, and another state is space invaders etc.   Another question also is How would I be able to use this to create a Pause state in my gameplay? Is it something like when Paused is pressed through out gameplay, currently I destroy the previous state. But If I am pausing the game I want to take it back to exactly the same state as it was previously. Is that where I would have to put my gameplay state into a stack, run my pause state, then when the player unpauses, delete the pause state completely, and pop the gameplay state off the stack, which has saved all the variables like player position and what was on the screen at the time. Short question for above would be if I pushed the gameplay state onto a stack, ran the pause state, then popped the gameplay state back as the current state, then it would continue where it left off? (In theory anyway!).   I actually need a stack at least for just the gameplay so I can pause don't I? :)   Does this sound like I am understanding this?   Thanks for reading   werdy666
  3. collision detection in maze issue

    My ultimate goal for this will be a little game, something like Boulderdash crossed with Pacman.   Using a fixed player speed and having a time step that can change, I have made the player aligned to the grid now which, so far, is still working. Or I can have set player speed in pixels, and keep the time step fixed. In essence making sure the player can only move 1,2,4,8,16 or 32 pixels every update.   This line needs some clarification. If the player starts moving down before being fully in the maze cell, he'll end up moving through the wall. The character MUST continue moving in the original direction of travel to clear the wall. That is, unless you plan on rotating the character, at which point you would be better off doing a radius collision test. It would help if we knew more of your ultimate goals for this.   My original problem was that my grid is 32x32, the player is also 32x32. When I was using a fixed time step with a variable player speed, the player would move as an example 6 pixels each update. I would then hit a wall, which as an example,was only 2 pixels away from the player and the collision code would stop him moving but still allow him to move the 2 pixels to be right against the wall. then going back along that same path traveling at 6 pixels a move, he would never be perfectly aligned with a corridor anymore and would not be able to move back through that corridor.   - I will make my own Pacman one day and I think I can understand the cornering for Pacman. This allows him to get away from ghosts who can't cut corners. I assume the original Pacman didn't have to worry about time steps etc because they knew exactly how fast the game was going to run because the hardware was the same for everyone. IE Arcade machines, C64's etc.
  4. collision detection in maze issue

    I'm still new and only recently have started using a fixed time step for my game loops in any of my programming adventures. Is there anything wrong with having multiple fixed time steps in a game?   First the rendering is unlimited of course.   Then a time step for AI/enemies etc.   Then another time step for the player.   What I have ended up doing is something simple and with the small amount of testing so far seems to work.   The fixed time step in the above code is 1/60.f. With my player speed at 400.f works out to be approx 6.6 pixels each update. So what I have done is instead of using the time step in my move function, I have just got the player sprite to move 2 pixels. This allows the sprite to always be "divisible???" of 32 and therefore will always land perfectly on an intersection. 4,8,16 and 32 also work.(X2 )? One thing I have discovered is that if I adjust the Fixed time step to 1/120.f then my player sprite doubles the speed. I can also adjust it to say 1/80.f and have no issues with the player moving in and around intersections.   So in effect I have the ability to move the player sprite 1 pixel each time but adjust the speed via the fixed time step. Will my theory work out ok? I'm not making Quake 5 or anything, but I just want to make sure that if I run my game on another machine, be it faster or slower, It will still perform the same.   Obviously when the time comes for bad guys and AI. I would use a different time step that is actually fixed.   Thanks again for all your input!   Werdy666
  5. Hi,   I have been able to successfully generate a random maze but am having issues with the collision detection for a simple square moving around the maze.   I have been able to get it to work effectively. My issue I think is in the timestep.   My current issue is that when the square is moving along the maze and then comes across a T intersection. Refer picture for better explanation   [attachment=29136:collisionDetectionIssue.jpg]   The blue player cannot go down.   I thought of one way to do it is that when the player stops moving, check to see which direction they were moving and if it is say 3 pixels away from covering the tile completely then move the extra 3 pixels. The problem with this is that if I'm moving say left and down, it still won't go in the down direction until I stop moving.   Currently in my code I check all 4 points of the blue square to see what tile it is going to move into. so when he is in that position going down the Right bottom corner will be in a wall so it won't let him move down.   Here is all the code for main.cpp. I will eventually move it into classes etc, but just want to get it working properly first. #include "main.h" std::vector <int> MazeData; int TileSizeX = 32; int TileSizeY = 32; int playersize = 32; int scale = 1; // not in use currently int MazeSizeX = 15; int MazeSizeY = 15; struct collision { bool TopLeft; bool TopRight; bool BottomLeft; bool BottomRight; }; collision CheckCollision(sf::Vector2f PlayerPosition, int movex, int movey); // check to see if new position is valid int main() { float TimePerFrame = 1.f / 60.f; // 60 updates a second float timesincelastupdate = 0; sf::Clock DeltaTime; sf::Clock FPS; DeltaTime.restart().asSeconds(); FPS.restart().asSeconds(); int framerate = 0; float DT; // Delta Time sf::RenderWindow mywindow(sf::VideoMode(912,912),"Mazes"); srand( unsigned (time(0))); MazeData.resize(MazeSizeX*MazeSizeY); MazeGenerator NewMaze; NewMaze.GenerateNewMaze(MazeData, MazeSizeX, MazeSizeY); sf::Sprite Wall; sf::Sprite Floor; sf::Sprite Player; sf::Texture WallTexture; sf::Texture FloorTexture; sf::Texture PlayerTexture; PlayerTexture.loadFromFile("./Res/Player.png", sf::IntRect(0, 0, playersize, playersize)); WallTexture.loadFromFile("./Res/Wall.png", sf::IntRect(0, 0, TileSizeX, TileSizeY)); FloorTexture.loadFromFile("./Res/Floor.png", sf::IntRect(0, 0, TileSizeX, TileSizeY)); Wall.setTexture(WallTexture); Floor.setTexture(FloorTexture); Player.setTexture(PlayerTexture); // setup player int x = 1; int y = 1; Player.setPosition(x * TileSizeX, y * TileSizeX); float PlayerSpeed = 400.0f; int MoveX = 0; int MoveY = 0; while (mywindow.isOpen()) { sf::Event event; while (mywindow.pollEvent(event)) { if (event.type == sf::Event::Closed) mywindow.close(); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { mywindow.close(); } while (timesincelastupdate > TimePerFrame) { MoveY = 0; MoveX = 0; timesincelastupdate -= TimePerFrame; if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { MoveY += -1; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { MoveY += 1; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { MoveX += -1; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { MoveX += 1; } float PlayerPosX = 0; float PlayerPosY = 0; if (MoveX != 0) { PlayerPosX = Player.getPosition().x; float test = PlayerPosX; PlayerPosY = Player.getPosition().y; if (MoveX == 1) { PlayerPosX += TileSizeX; // if player moving right, check right side of player } PlayerPosX += MoveX * PlayerSpeed * TimePerFrame; int tilex = PlayerPosX / TileSizeX; int tiley = PlayerPosY / TileSizeY; int newtile = tilex + (tiley * MazeSizeX); if (MazeData[newtile] != 0) { collision collide = CheckCollision(Player.getPosition(), MoveX, 0); if (collide.TopLeft == false && collide.TopRight == false && collide.BottomLeft == false && collide.BottomRight == false) { Player.move(TimePerFrame * PlayerSpeed * MoveX, 0); // no collision so move player } } if (MoveX == -1 && MazeData[newtile] == 0) // moving left and hit wall tile so we move player up against wall { int xtile = newtile % MazeSizeX; int ytile = newtile / MazeSizeX; Player.setPosition((xtile * TileSizeX) + TileSizeX, Player.getPosition().y); } if (MoveX == 1 && MazeData[newtile] == 0) // moving right and hit wall tile so we move player up against wall { int xtile = newtile % MazeSizeX; int ytile = newtile / MazeSizeX; Player.setPosition((xtile * TileSizeX) - TileSizeX, Player.getPosition().y); } } if (MoveY != 0) { PlayerPosX = Player.getPosition().x; PlayerPosY = Player.getPosition().y; PlayerPosY += MoveY * PlayerSpeed * TimePerFrame; int tilex = PlayerPosX / TileSizeX; if (MoveY == 1) { PlayerPosY += TileSizeY; } int tiley = PlayerPosY / TileSizeY; int newtile = tilex + (tiley * MazeSizeX); if (MazeData[newtile] != 0) { collision collide = CheckCollision(Player.getPosition(), 0, MoveY); if (collide.TopLeft == false && collide.TopRight == false && collide.BottomLeft == false && collide.BottomRight == false) { Player.move(0, TimePerFrame * PlayerSpeed * MoveY); } } if (MoveY == -1 && MazeData[newtile] == 0) // moving left and hit wall tile so we move player up against wall { int xtile = newtile % MazeSizeX; int ytile = newtile / MazeSizeX; Player.setPosition(Player.getPosition().x, (ytile * TileSizeY) + TileSizeY); } if (MoveY == 1 && MazeData[newtile] == 0) // moving right and hit wall tile so we move player up against wall { int xtile = newtile % MazeSizeX; int ytile = newtile / MazeSizeX; Player.setPosition(Player.getPosition().x, (ytile * TileSizeY) - TileSizeY); } } } mywindow.clear(sf::Color::Blue); // DRAW TILES for (int x = 0; x < MazeSizeX; x++) { for (int y = 0; y < MazeSizeY; y++) { int a = MazeData[x + y * MazeSizeX]; if (a == 0)//draw wall { Wall.setPosition(x * TileSizeX * scale, y * TileSizeY * scale); mywindow.draw(Wall); } else // draw floor { Floor.setPosition(x * TileSizeX * scale, y * TileSizeY * scale); mywindow.draw(Floor); } } } // draw player mywindow.draw(Player); mywindow.display(); framerate++; DT = DeltaTime.getElapsedTime().asSeconds(); timesincelastupdate += DT; PlayerMovecount -= DT; DeltaTime.restart().asSeconds(); // if (FPS.getElapsedTime().asSeconds() > 1.0) { // 1 second has passed so print FPS in title mywindow.setTitle("Mazes V0.3 | " + std::to_string(framerate) + " FPS"); framerate = 0; FPS.restart().asSeconds(); } } return 0; } collision CheckCollision(sf::Vector2f PlayerPosition, int movex, int movey) { collision testcollision{ false, false, false, false }; float PosX = PlayerPosition.x + movex; float PosY = PlayerPosition.y + movey; int tilex = (PosX / TileSizeX); int tiley = (PosY / TileSizeY); int newtileTL = tilex + (tiley * MazeSizeX); tilex = (PosX + TileSizeX -1) / TileSizeX; // top right tiley = (PosY / TileSizeY); int newtileTR = tilex + (tiley * MazeSizeX); tilex = (PosX / TileSizeX ); // Bottom Left; tiley = (PosY + TileSizeY-1) / TileSizeY; int newtileBL = tilex + (tiley * MazeSizeX); tilex = (PosX + TileSizeX-1) / TileSizeX; tiley = (PosY + TileSizeY-1) / TileSizeY; int newtileBR = tilex + (tiley * MazeSizeX); if (MazeData[newtileTL] == 0) { testcollision.TopLeft = true; } if (MazeData[newtileTR] == 0) { testcollision.TopRight = true; } if (MazeData[newtileBL] == 0) { testcollision.BottomLeft = true; } if (MazeData[newtileBR] == 0) { testcollision.BottomRight = true; } return testcollision; } Thanks   P.S. Yeah I am a beginner so be gentle!
  6. A Beginners DFS Maze Problem

    Thanks Spidi. - And Eck, I will take your recommendation too!   1. I do see tutorials that will not use them and some that use brackets even if it is one command. I personally like that brackets cause I find it easier to read myself.   2. My naming convention does need work. The more I code the more I will get it right. Practice makes perfect. You should see my class member names. Gotta remember to use m_ for them!   3. Yeah I kinda put that in ready for when I can start using mazes of a different height to width. Also I will use a vector rather than an array so I can decide at run time the size of the maps.   4. Yeah I have since cleaned up my code a little, I haven't yet put that into a function but I will. Just gotta work out the logistics of it all. Any problems with it I know where to ask for help!   I knew it would be something simple. I have used the debugger in VS 2013 and even watched the directions change each time..... I do like the debugger, it does come in handy when I want to make sure a variable has a value and when it has one I did not think it should, I go straight to my code and work it out from there. I think being fairly rusty( haven't touched any programming for like 4 years now) I think I assumed that the Directions vector was not global casue it was in a class. Didn't cross my mind that it was global to the class itself!
  7. A Beginners DFS Maze Problem

    Hi,   I have been using this site www.migapro.com/depth-first-search/ to learn about how to do mazes   I have got it setup and it works ok but I have a problem. Sometimes when the map is created it doesn't find every possible path to create a maze. I have been able to work out a formula based on the size of the maze to determine how many grid tiles should be used to make the map, and if that size is not correct, then redo the map.   I'd like not to have to redo the whole map, or understand why it fails to fill all possible grid positions.   I'm still a beginner and am starting to understand how the recursion works. If you could have a look over my code and point out what I should be looking at to find the error. It only happens like 1 in 10 times. I think it is in the direction it randomly chooses to travel in....( in this case it didn't go "up" at all.   Here is a picture of one of the bad maps.   [attachment=29068:badmaze.jpg]   and here is the code: GenerateMaze::GenerateMaze(int mazex, int mazey) { numberofcells = mazesize*mazesize; mazesizex = mazex; mazesizey = mazey; Directiontotravel.push_back(Direction::Up); Directiontotravel.push_back(Direction::Down); Directiontotravel.push_back(Direction::Left); Directiontotravel.push_back(Direction::Right); } bool GenerateMaze::GenerateNewMaze(int mazearray[], int mazexsize, int mazeysize) { system("CLS"); // maze maker magic // use recursion rather than a stack. ClearMaze(mazearray); int startpoint = mazesize+1; Visited[startpoint] = true; mazearray[startpoint] = 1; int xposcell = startpoint % mazesizex; // x pos in tiles int yposcell = startpoint / mazesizey; // y pos in tiles // reduce number of cells by 1 for starting location aswell numberofcells--; // call recursion function bool succeeded = Generate(mazearray, xposcell, yposcell); return succeeded; } bool GenerateMaze::Generate(int mazearray[], int x, int y) { int newtile = -1; int betweentile = -1; std::random_shuffle(Directiontotravel.begin(), Directiontotravel.end()); for (int a = 0; a < (int)Directiontotravel.size(); a++) { switch (Directiontotravel[a]) { case Direction::Up: if (y - 2 <= 0) continue; newtile = x + ((y-2) * mazesizex); betweentile = x + ((y - 1) * mazesizex); if (!Visited[newtile] && !Visited[betweentile]) // tiles have not been visited { Visited[newtile] = true; Visited[betweentile] = true; mazearray[newtile] = 1; mazearray[betweentile] = 1; numberofcells -= 2; int newx = newtile % mazesizex; int newy = newtile / mazesizey; Generate(mazearray, newx, newy); } break; case Direction::Down: if (y + 2 >= mazesizey - 1) continue; newtile = x + ((y + 2) * mazesizex); betweentile = x + ((y + 1) * mazesizex); if (!Visited[newtile] && !Visited[betweentile]) // tiles have not been visited { Visited[newtile] = true; Visited[betweentile] = true; mazearray[newtile] = 1; mazearray[betweentile] = 1; numberofcells -= 2; int newx = newtile % mazesizex; int newy = newtile / mazesizey; Generate(mazearray, newx, newy); } break; case Direction::Left: if (x - 2 <= 0) continue; newtile = (x - 2) + (y * mazesizex); betweentile = (x - 1) + (y * mazesizex); if (!Visited[newtile] && !Visited[betweentile]) // tiles have not been visited { Visited[newtile] = true; Visited[betweentile] = true; mazearray[newtile] = 1; mazearray[betweentile] = 1; numberofcells -= 2; int newx = newtile % mazesizex; int newy = newtile / mazesizex; Generate(mazearray, newx, newy); } break; case Direction::Right: if (x + 2 >= mazesizex - 1) continue; newtile = (x + 2) + (y * mazesizex); betweentile = (x + 1) + (y * mazesizex); if (!Visited[newtile] && !Visited[betweentile]) // tiles have not been visited { Visited[newtile] = true; Visited[betweentile] = true; mazearray[newtile] = 1; mazearray[betweentile] = 1; numberofcells -= 2; int newx = newtile % mazesizex; int newy = newtile / mazesizex; Generate(mazearray, newx, newy); } break; } } return true; } bool GenerateMaze::ClearMaze(int mazearray[]) { for (auto &a : Visited) { a = false; } for (int x = 0; x < mazesizex*mazesizey; x++) { mazearray[x] = 0; } return true; } Thanks for reading   werdy666
  8. hi, I am currently working on a 2d shooter type game and so far am quite happy with what i have achieved. first time I have had animation in any of my programs and it seems to work. I am still learning classes and pointers and don't fully understand everything but as I go on I think it will become clearer. I have attached my main.cpp file. I think it is over bloated and not very clear programming. there is nothing wrong with it I just think I could be doing things better. Any hints and tips and advice would be greatly appreciated. I know some of my naming conventions are strange but I think that will come with practice too. main.cpp #include "shooter.h" SDL_Surface* alien01bitmap = NULL; SDL_Surface* explosionspritesheet = NULL; SDL_Surface* playerspritesheet = NULL; SDL_Surface* playerbulletsspritesheet = NULL; SDL_Surface* explosionsprite = NULL; SDLGraphics* gscreen = NULL; Input* ginput = NULL; Timer* fps = NULL; Timer* animtimer = NULL; Sprite* playerone = NULL; Sprite* alienone = NULL; Sprite* playerbullets = NULL; Sprite* gexplosions = NULL; Sprite* alienbullets = NULL; const int maxnumofexplosions = 11; const int maxnumofaliens = 10; const int maxnumofplayerbullets = 5; const int maxnumofalienbullets = 5; int playerlives = 3; int score = 0; float playerbulletdelay = 0.5f; float playerspeed = 150.0f; float playerbulletspeed = 200.0f; bool playerdead = false; SDL_Rect camera = {0,0,0,0}; // camera for the map area of the screen to allow scrolling per tile size ( not smooth scrolling.) void Handleinput(); void checkforcollisions(); bool check_collision( SDL_Rect A, SDL_Rect B); float randomdelay = 0.0f; float bulletdelay = 0.5f; bool gamerunning = true; bool mousereleased = true; float timerforanim = 0.0f; int main (int argc, char* args[]) { putenv("SDL_VIDEODRIVER=directx") ; putenv("SDL_VIDEO_WINDOW_POS=40,40") ; gscreen = new SDLGraphics(1280,970,"Shooter!!! V0.1 28 December 2009 (00:12)",50,50,50); ginput = new Input(); fps = new Timer(); animtimer = new Timer(); alienbullets = new Sprite[maxnumofalienbullets]; playerbullets = new Sprite[maxnumofplayerbullets]; alienone = new Sprite[maxnumofaliens]; playerone = new Sprite(); //(gscreen,"player1.bmp",8,64,200,20,600,700, true); gexplosions = new Sprite[maxnumofexplosions]; alien01bitmap = gscreen->loadBitmap("alien03.bmp",255,0,255); for(int a = 0; a < maxnumofaliens;a++) { alienone[a].createnewSprite(gscreen,alien01bitmap,17,64,10,false, AlienSprite); } playerspritesheet = gscreen->loadBitmap("player1.bmp",255,0,255); playerone->createnewSprite(gscreen,playerspritesheet,8,64,10,true, PlayerSprite); playerbulletsspritesheet = gscreen->loadBitmap("bullets1.bmp",255,0,255); for(int a = 0; a < maxnumofalienbullets;a++) { alienbullets[a].createnewSprite(gscreen,playerbulletsspritesheet,4,8,10,false, BulletSprite); } for(int a = 0; a < maxnumofplayerbullets;a++) { playerbullets[a].createnewSprite(gscreen,playerbulletsspritesheet,4,8,10,false, BulletSprite); } explosionsprite= gscreen->loadBitmap("explosions8.bmp",255,0,255); for (int a = 0 ; a < maxnumofexplosions; a++) { gexplosions[a].createnewSprite(gscreen,explosionsprite,25,64,25,false, ExplosionSprite); int number = rand()%8+1; gexplosions[a].setcurrentsprite(number); } for(int a = 0; a < maxnumofaliens;a++) { int temp = rand()%1000 + 100; alienone[a].setup(temp, -70,false,150.0f); } playerone->setup(600,600,true,200.0f); randomdelay = rand()%100 / 100.0f; while (gamerunning) { timerforanim = animtimer->timeSinceLastFrame(); randomdelay -= timerforanim; bulletdelay -= timerforanim; if (randomdelay < 0.0f) { for (int a = 0; a < maxnumofaliens; a++) { if (!alienone[a].getalive()) { float xpos = rand()%1000 + 100; float speed = rand()%100 +150; alienone[a].setup(xpos,-70,true, speed); a += maxnumofaliens; // get out of loop } } randomdelay = rand()%100 / 100.0f; } ginput->readInput(); if (ginput->windowClosed()) { gamerunning = false; } Handleinput(); for (int a = 0 ; a < maxnumofexplosions; a++) { gexplosions[a].updateanim(timerforanim); } if ( (playerdead == true) && (gexplosions[10].getalive() == false )) { playerone->setposition( 600,300); playerone->setalive(true); playerdead = false; if (playerlives ==0) gamerunning = false; } for(int a = 0; a < maxnumofaliens;a++) { alienone[a].updateanim(timerforanim); alienone[a].updateposition(timerforanim); } playerone->updateanim(timerforanim); playerone->updateposition(timerforanim); // for(int a = 0; a < maxnumofplayerbullets;a++) { playerbullets[a].updateanim(timerforanim); playerbullets[a].updateposition(timerforanim); } // for(int a = 0; a < maxnumofalienbullets;a++) { alienbullets[a].updateanim(timerforanim); alienbullets[a].updateposition(timerforanim); } // begin drawing gscreen->beginScene(); for(int a = 0; a < maxnumofaliens;a++) { alienone[a].drawSprite(); } playerone->drawSprite(); for (int a = 0 ; a < maxnumofplayerbullets; a++) { playerbullets[a].drawSprite(); } for (int a = 0 ; a < maxnumofalienbullets; a++) { alienbullets[a].drawSprite(); } for (int a = 0 ; a < maxnumofexplosions; a++) { gexplosions[a].drawSprite(); } gscreen->endScene(); //end drawing // pick a random number and see if alien will shoot. int shoot = rand()%100; if (shoot < 4) { for (int a=0; a < maxnumofalienbullets;a++) { if (!alienbullets[a].getalive()) { int pickalien = rand()%maxnumofaliens; if (alienone[pickalien].getalive() && (alienone[pickalien].getYposition() > 0)) { alienbullets[a].setcurrentsprite(2); alienbullets[a].setup(alienone[pickalien].getXposition()+16,alienone[pickalien].getYposition()+32,true,500.0f); } a += maxnumofalienbullets; } } } checkforcollisions(); } gscreen->closeBitmap(alien01bitmap); gscreen->closeBitmap(explosionsprite); gscreen->closeBitmap(playerspritesheet); gscreen->closeBitmap(playerbulletsspritesheet); delete []gexplosions; delete []playerbullets; delete playerone; delete []alienone; delete ginput; delete fps; delete animtimer; delete gscreen; return 0; } void Handleinput() { bool *keysheld = ginput->getInputKeys(); bool* MouseButtons = ginput->getInputMouseButtons(); int* MousePosition = ginput->getInputMousePosition(); if (keysheld[SDLK_ESCAPE]) { gamerunning = false; } if (keysheld[SDLK_LEFT]) { playerone->moveleft(); } else if (keysheld[SDLK_RIGHT]) { playerone->moveright(); } else { playerone->stopmovingx(); } if (keysheld[SDLK_UP]) { playerone->moveup(); } else if (keysheld[SDLK_DOWN]) { playerone->movedown(); } else { playerone->stopmovingy(); } if (keysheld[SDLK_z]) { if (bulletdelay < 0.0f) { for (int a = 0; a < maxnumofplayerbullets; a++) { if( (!playerbullets[a].getalive()) && (playerone->getalive())) // if alive is false { playerbullets[a].setup( playerone->getXposition()+26, playerone->getYposition(),true, -300.0f); bulletdelay = 0.5f; a+= maxnumofplayerbullets; } } } } if (!MouseButtons[LEFTMOUSEBUTTON]) { mousereleased = true; } if ( MouseButtons[LEFTMOUSEBUTTON]) { mousereleased = false; } if ( MouseButtons[RIGHTMOUSEBUTTON]) { } } void checkforcollisions() { SDL_Rect play = playerone->getPosforCollisioncheck(); SDL_Rect playbullet; for (int a=0;a < maxnumofaliens; a++) { if (alienone[a].getalive() && playerone->getalive()) { SDL_Rect baddy = alienone[a].getPosforCollisioncheck(); if ( check_collision(play,baddy) ) { gexplosions[10].setup( playerone->getXposition(), playerone->getYposition(), true, 0.0f); playerone->setalive(false); playerlives -= 1; playerdead = true; } for (int s = 0; s < maxnumofplayerbullets; s++) { if (playerbullets[s].getalive()) { playbullet = playerbullets[s].getPosforCollisioncheck(); if ( check_collision(playbullet,baddy) ) { // begin an explosion animation; gexplosions[a].setup( (alienone[a].getXposition()),(alienone[a].getYposition()),true, 30); alienone[a].setup( (rand()%1000) +100, -70, false, (rand()%100)+100 ); playerbullets[s].setalive(false); } } } } } for (int a=0; a < maxnumofalienbullets;a++) { if ((alienbullets[a].getalive()) && (playerone->getalive())) { SDL_Rect badbullet = alienbullets[a].getPosforCollisioncheck(); if ( check_collision(play,badbullet)) { playerone->setalive(false); gexplosions[10].setup( (playerone->getXposition()),(playerone->getYposition()),true, 30); playerone->setalive(false); playerlives -= 1; playerdead = true; alienbullets[a].setalive(false); } } } } bool check_collision( SDL_Rect A, SDL_Rect B ) { //The sides of the rectangles int leftA, leftB; int rightA, rightB; int topA, topB; int bottomA, bottomB; //Calculate the sides of rect A leftA = A.x; rightA = A.x + A.w; topA = A.y; bottomA = A.y + A.h; //Calculate the sides of rect B leftB = B.x; rightB = B.x + B.w; topB = B.y; bottomB = B.y + B.h; //If any of the sides from A are outside of B if( bottomA <= topB ) { return false; } if( topA >= bottomB ) { return false; } if( rightA <= leftB ) { return false; } if( leftA >= rightB ) { return false; } //If none of the sides from A are outside B return true; }
  9. Collision Detection help!

    Hi, I'm having trouble getting my collision detection code to work properly on a fast moving object. currently am using time based movement to move a sprite at high velocity with another sprite on the screen. think pong. my problem arises when the ball sprite is moving fast and goes straight through the bat. i'm using basic bounding box collision detection. here is some code... bool check_collision( SDL_Rect A, SDL_Rect B ) { //The sides of the rectangles int leftA, leftB; int rightA, rightB; int topA, topB; int bottomA, bottomB; //Calculate the sides of rect A leftA = A.x; rightA = A.x + A.w; topA = A.y; bottomA = A.y + A.h; //Calculate the sides of rect B leftB = B.x; rightB = B.x + B.w; topB = B.y; bottomB = B.y + B.h; //If any of the sides from A are outside of B if( bottomA < topB ) { return false; } if( topA > bottomB ) { return false; } if( rightA < leftB ) { return false; } if( leftA > rightB ) { return false; } //If none of the sides from A are outside B return true; } thats my basic collision function. while (gamerunning) { player.x = gameplayer->currentxpos(); player.y = gameplayer->currentypos(); player.w = 50; player.h = 10; object[0].x = ball[0].currentxpos(); object[0].y = ball[0].currentypos(); object[0].w = 14; object[0].h = 14; object[1].x = ball[1].currentxpos(); object[1].y = ball[1].currentypos(); object[1].w = 14; object[1].h = 14; float DeltaTime = gametimer->timeSinceLastFrame(); gamescreen->BeginScene(); handleinput(); for ( int x = 0; x < 1; x++) { // check balls for collision with player if (check_collision( player,object[x]) == true) { if (!(ball[x].currentypos()+12 > gameplayer->currentypos())) { ball[x].Setspeed(ball[x].GetSpeedY()+70.0f); ball[x].MoveUp(); } } Thats the start of my main game loop. I believe my problem is related to the fact that the ball maybe moving at more than 10 pixels a frame. my players bat is 10 pixels thick. I'm just experimenting at the moment with the code but just can't seem to work out the problem. debugging my code suggests that when I have the topspeed of the ball as 1000 the movement is still not 2 pixels a frame as my float gets rounded down from about 1.8 to an int of just 1. Hope someone can push me in the right Direction! :)
  10. TimeBased Movement question/observation

    http://lazyfoo.net/SDL_tutorials/lesson32/index.php if i download, compile and run that source code i get what i call jerkiness in the movement. I am just wondering is there something wrong with the particular way the code handles movement, or is it more SDL causing the problems cause it isn't hardware accelerated? Werdy666
  11. Hi, I am currently experimenting with SDL and time based movement for a little sprite I can control. When I use time based movement it seems a little jerky to me, not smooth like pixel based movement is. Is this due to the fact that SDL isn't using the 3d hardware acceleration of the video card? A long time ago I played a little with opengl and moving a quad on the screen and from what i remember it looks a lot smoother no matter how fast or slow the speed of the quad. I am assuming that opengl is smoother because... Hardware acceleration opengl uses floats for screen coords and sdl blitting can only use ints. is this right or do i have no diea what i am talking about? thanks Werdy666
  12. A Homework Question.

    umm more precisely, is there anywhere on the net I can actually get small challenges to help me put into practice what I read in tutorials on c++? the sort of challenges I mean are like from the basic for loops, input/output to the likes of classes, pointers and references. Any links and tips would be appreciated! Werdy666:)
  • Advertisement