I am making an ncurses game which has a spaceship fire bullets at other enemies.
I've got the ship firing bullets how ever when I fire more than one bullet, only the latest bullet will move and the rest will stay still.
int i=0 , j=-1;
switch(key){
case KEY_UP: playership.row=changeRow(playership.row,-1,playership.col); /* move up */
break;
case KEY_DOWN: playership.row=changeRow(playership.row,+1,playership.col); /* move down */
break;
case KEY_LEFT:playership.col=changeColumn(playership.col,-1,playership.row); /* move left */
break;
case KEY_RIGHT:playership.col=changeColumn(playership.col,+1,playership.row); /* move right */
break;
case ' ': {j++; bullets[0].col=playership.col+5; bullets[j].row=playership.row-2 ;break;}
default: break; /* do nothing if other keys */
}
if (j!=-1){
attrset(COLOR_PAIR(2));
mvprintw(bullets[j].row,bullets[0].col,"%c",bullet);
mvprintw(bullets[j].row+1,bullets[0].col," ");
bullets[j].row=bullets[j].row-1;
refresh();
}
I tried to implement the suggestion from the comments in this answer to my earlier question, but I don't think I've done it right:
If you can have 5 bullets at once, you need to store their positions.
If you have int bullet_pos[5] that would be fine. You could use -1 in
each position to say that no bullets are active. Then when you want to
fire one you search the array to find the first position that is -1
and change it to 0. When you draw the bullets, you go through the
array and draw a bullet for any position that is not -1, and update
its position.
If you don't already, try adding a flag to your bullet structure. Something like alive.
When you want to fire, you check through your array and find an unused bullet position (if any):
for( int i = 0; i < MAX_BULLETS; i++ ) {
if( !bullets[i].alive ) {
bullets[i].alive = true;
bullets[i].row = playership.row;
bullets[i].col = playership.col+5;
break;
}
}
Then when you update or draw:
for( int i = 0; i < MAX_BULLETS; i++ ) {
if( bullets[i].alive ) {
attrset(COLOR_PAIR(2));
mvprintw(bullets[i].row, bullets[i].col, "%c", bullet);
mvprintw(bullets[i].row+1, bullets[i].col, " " );
bullets[i].col++;
// TODO check for bullet death. If bullet is done, set `alive` to false.
}
}
refresh();
Related
For some reason when I run the code below... The character only moves diagonally down. Lets say line I"m drawing is character:
\
\
\
\
\
That's the only direction it moves if I press up, right, down or left key!
Please help, I want to go right if right, up if up, down if down, and left if left.
My Code is:
#include<iostream>
#include<string>
#include<SFML\Graphics.hpp>
using std::cout;
using std::endl;
enum Direction
{
DOWN,
LEFT,
RIGHT,
UP
};
int main()
{
sf::RenderWindow _Win(sf::VideoMode(600, 600), "Hello World");
sf::Texture _texture;
if (!(_texture.loadFromFile("Resources/SPRITE.png")))
{
cout << "Could not load iamge" << endl;
}
//Source, tell us our starting position.
//Vector2i = Vector of 2 in SFML
sf::Vector2i source(1, DOWN/*or 0*/);
sf::Sprite _sprite(_texture);
float x = _sprite.getPosition().x;
float y = _sprite.getPosition().y;
while (true)
{
sf::Event _event;
while (_Win.pollEvent(_event))
{
switch (_event.type)
{
case sf::Event::Closed:
_Win.close();
exit(1);
break;
case sf::Event::KeyPressed:
switch (_event.key.code)
{
case sf::Keyboard::Up:
source.y = UP;
_sprite.move(sf::Vector2f(x,y--));
y = 3, x=3;
break;
case sf::Keyboard::Down:
source.y = DOWN;
_sprite.move(sf::Vector2f(x, y++));
y = 3, x = 3;
break;
case sf::Keyboard::Right:
source.y = RIGHT;
_sprite.move(sf::Vector2f(x++, y));
y = 3, x = 3;
break;
case sf::Keyboard::Left:
source.y = LEFT;
_sprite.move(sf::Vector2f(x--, y));
y = 3, x = 3;
break;
}
break;
}
}
//Cropping Out Image
//Please Look at sprite in resources/Sprite.png
//When we run this :
//_sprite.setTextureRect(sf::IntRect( source.x*32 , source.y*32 , 32 , 32 ));
//Its going to give us the top left corner sprite image. Thats so because
//we are cropping source.x*32 , which of 32 is the width of the sprite.. So it
//starts from 1 * 32. 32 is the width of one sprite so it goes to the end of it.
//Same Applies to the y. source.y * 32. It just goes to the end of the down sprite.
//As you go down the y increases, 1 * 32 = 32. And 32 is the width of one sprite
//so it shows body of one full sprite.
_sprite.setTextureRect(sf::IntRect( source.x*32 , source.y*32 , 32 , 32 ));
//Clears Window(Flickering..)
_Win.clear();
//Draw Sprite
_Win.draw(_sprite);
//And Finally Display the Window.
_Win.display();
}
}
In every case of your switch statement, you move the sprite by (x,y), and then either increment or decrement x or y, depending upon the direction. However, this is fruitless, since on the very next line, you reset them both to 3. So in effect, whatever direction key is pressed, you are doing this:
_sprite.move(sf::Vector2f(3, 3));
That is, 3 units to the right and 3 units down, which seems to fit your description of the movement you are seeing. I'm not sure what kind of movement you're going for, but here's an example that could work:
switch (_event.key.code) {
case sf::Keyboard::Up:
_sprite.move(sf::Vector2f(0, -3));
break;
case sf::Keyboard::Down:
_sprite.move(sf::Vector2f(0, 3));
break;
case sf::Keyboard::Right:
_sprite.move(sf::Vector2f(3, 0));
break;
case sf::Keyboard::Left:
_sprite.move(sf::Vector2f(-3, 0));
break;
}
This would move the sprite 3 units each time a direction key was pressed, in that direction.
I'm trying to create a smaller game and I need to get a rectangle to move left to right within the window. Note that this is not the fully completed code. Below is a snippet of a created window class and the run function of it.
I can draw the rectangle, and at the moment it's also moving. However, when I'm pressing up/down it'll move to the right as well, but I want it to do it automatically. If I move the for-loop calling movement() outside of while (which I assume it should..?), the rectangle just disappears.
Another thing to note is that movement should be called through the vector pcEnhet, since I'll use it with other sprites later on.
void Spelplan::run() {
SDL_RenderClear(render);
for (PCKomponent* k : pcEnhet)
k->draw();
SDL_RenderPresent(render);
bool spela = true;
while (spela) {
SDL_Event eve;
while (SDL_PollEvent(&eve)) {
switch (eve.type) {
case SDL_QUIT:
spela = false;
break;
case SDL_KEYDOWN:
switch (eve.key.keysym.sym) {
case SDLK_DOWN:
for (PCKomponent* k : pcEnhet)
k->knappNer(eve);
break;
case SDLK_UP:
for (PCKomponent* k : pcEnhet)
k->knappUpp(eve);
break;
}//keysym switch
SDL_RenderClear(render);
for (PCKomponent* k : pcEnhet)
k->draw();
SDL_RenderPresent(render);
}//eve.type switch
for (PCKomponent* k : pcEnhet) {
k->movement();
k->draw();
}
}//while SDL_Poll
}//while spela
}
void Spelare::movement() {
area.x++;
}
void Spelare::draw() {
SDL_RenderCopy(sp->getPlan(), spelareTexture, NULL, &area);
}
Don't do the rendering in while (SDL_PollEvent(&eve)), but in while (spela). Your items have to be moved/drawn not depending on whether the input is being registered.
while (SDL_PollEvent(&eve)) {
...
}
SDL_RenderClear(render);
for (PCKomponent* k : pcEnhet) {
k->movement();
k->draw();
}
SDL_RenderPresent(render);
Remove the "pre-rendering" code you have above the bool spela = true; line, and remember to make your event loop similar to this from now on.
Note that rather than moving all the objects, you could think of them as stationary and move just the camera (viewport), with which you would calculate the absolute coordinates of the objects in their draw function.
And also, pick one from the two:
spela = false; // will render one last frame
break; // ^ will not, and does not require spela variable at all
I'm writing code that draws a polygon and gives it two feet, walks from the right until it gets to the middle, does a flip, and then lands and walks to the left. I'm having a lot of trouble figuring out how to animate his feet. All I want to do is make one go up, then come down, then the other go up, and then come down. I know all I have to do is change the Y values of his feet, but I can't figure out how.
My professor talks about key frames a lot, but wouldn't every step that my "Polyman" would take be a key frame leading to infinite amount of cases? Here is my timer function...
void TimerFunction(int value) //float plx = 7.0, ply=-3.0, linet=0.00;
{
switch(frame)
{
case 1:
dx-=0.15;
plx-=0.15; //dx=polygon, plx = one foot, pl2x = other foot
pl2x-=0.15;
if(dx<=0.0)
{
plx=0.0; //this case makes polyman walk to the middle
dx=0.0;
pl2x=0.0;
frame=2;
}
break;
case 2:
dxt+=0.05;
if (dxt<=-0.00) //this is a triangle I translate over polyman appearing as if he's opening his mouth
{
dxt=0.00;
frame=3;
}
break;
case 3:
dy+=0.2;
theta+=10.0;
thetat+=10.0;
dyt+=0.2; //this is the flip with polyman's mouth open
ply+=0.2;
pl2y+=0.2;
linet2+=10.0;
linet+=10.0;
if(dy>5.0 || theta>360.00)
{
dy=5.0;
dyt=5.0;
ply=5.0;
pl2y=5.0;
linet2=0.0;
theta=0.0;
thetat=0.0;
linet=0.0;
frame=4;
}
break;
case 4:
dy-=0.2;
dyt-=0.2;
ply-=0.2;
pl2y-=0.2;
if(dy<=-3.0) //this is polyman coming back down to earth
{
dy=-3.0;
dyt=-3.0;
ply=-3.0;
pl2y=-3.0;
frame=5;
}
break;
case 5:
dxt-=0.2;
if (dxt<-3)
{ //this is the triangle slowly translating left appearing as if he's closing his mouth
dxt-=3.0;
}
if (dxt<=-8)
{
dxt = -8;
frame = 6;
}
break;
case 6:
dx-= 0.15;
plx-= 0.15;
pl2x-=0.15; //this is polyman walking off the stage to the left
if(dx<=-8.0)
{
dx=-8.0;
plx=-8.0;
pl2x=-8.0;
}
break;
}
glutPostRedisplay();
glutTimerFunc(30, TimerFunction, 1);
}
All variables that are used in my timerfunction are global. Thanks for your time! If you need any more of my code just ask and i'll append.
My first game in ALLEGRO 5 with c++.
It has a player that keeps moving continuously in right direction. From the right edge of the screen player faces obstacles like triangles and squares. These obstacles come alive at right edge of screen and die at left edge of screen.
Suppose X is triangle and O is square.
i want to create them in few combinations like
..{x} {xo} {xoox} {oxxo} {oxx}... And some variations(random maybe)
And after that I will randomize the occurence of these pattern.
SO I found a method to implement what i wanted. I used a switch() to randomly select various cases of combination. It works pretty well. But once in a while it overlaps even after I introduced a minimum gap xoff
Here is the code:
`//I have used srand(time(NULL)); once in main function too.
if(state == PLAYING)
{
ball->Moveball();
ball->Jumpball();
//Camera-----------
ball->Cameraupdate();
al_identity_transform(&camera);
al_translate_transform(&camera,-Cameraposition[0],-Cameraposition[1]);
al_use_transform(&camera);
if(rand() % 200==0)
{
xoff+=200;// to introduce a minimum gap between them but this also fail once in a while.
int ch;
ch=rand()%4;
switch(ch)
{
case 0:
//T
triangle = new Triangle(850 + Cameraposition[0]+xoff,319);
objects.push_back(triangle);
triangle->SetAlive(true);
break;
case 1:
//TT
triangle = new Triangle(850 + Cameraposition[0]+xoff,319);
objects.push_back(triangle);
triangle->SetAlive(true);
triangle = new Triangle(850 +30+ Cameraposition[0]+xoff,319);
objects.push_back(triangle);
triangle->SetAlive(true);
break;
case 2:
//S
square = new Square(850 + Cameraposition[0]+xoff,310);
objects.push_back(square);
square->SetAlive(true);
break;
case 3:
//SS
square = new Square(850 + Cameraposition[0]+xoff,310);
objects.push_back(square);
square->SetAlive(true);
square = new Square(850 +82+ Cameraposition[0]+xoff,310);
objects.push_back(square);
square->SetAlive(true);
break;
}
}
`
Problem solved :(For those who experienced similar doubt)The above code solves the problem of creating random combination of obstacles and generating those combinations randomly. But do check for collisions if you don't want to get overlapping combinations.
Just add another for loop:
void createObstacles(int numObstacles)
{
for(int i = 0; i < numObstacles; i++)
{
if(rand() % 2 == 0)
{
// Create a triangle.
}
else
{
// Create a square.
}
}
}
Call this every time you want to create obstacles, controlling the number of objects released at one time by changing the parameter numObstacles.
You can now do:
if(rand() % 200 == 0)
{
// Create anywhere from 1 to maxToCreate (which is 4) obstacles at a time.
const int maxToCreate = 4;
int numToCreate = (rand() % maxToCreate) + 1;
// Call the function to make some obstacles.
createObstacles(numToCreate);
}
Since your shapes are overlapping, either fix your initialization code to initialize them the way
I have gotten my basic L-System working and I decided to try and optimize the rendering of the application. Previously I was looping through the whole string of the L-System with a switch case and drawing. Better yet I will show you what I was doing:
for(unsigned int stringLoop = 0; stringLoop < _buildString.length(); stringLoop++)
{
switch(_buildString.at(stringLoop))
{
case'X':
//Do Nothing
//X is there just to facilitate the Curve of the plant
break;
case'F':
_prevState = _currState;
_currState.position += _currState.direction * stdBranchLength;
//Set the previous state to the current state
_graphics.SetColour3f(0.0f, 1.0f, 0.0f);
_graphics.Begin(OGLFlags::LINE_STRIP);
_graphics.Vertex3f(_prevState.position.X(), _prevState.position.Y(), _prevState.position.Z());
_graphics.Vertex3f(_currState.position.X(), _currState.position.Y(), _currState.position.Z());
_graphics.End();
break;
case'[':
_prevStack.push(_currState);
break;
case']':
_prevState = _currState;
_currState = _prevStack.top();
_prevStack.pop();
break;
case'-':
_currState.direction = _currState.direction.RotatedAboutZ(-(ROTATION) * Math::DegreesToRadians);
break;
case'+':
_currState.direction = _currState.direction.RotatedAboutZ(ROTATION * Math::DegreesToRadians);
break;
};
}
I removed all of this because I was literally resolving the tree every single frame, I changed this loop so that it would save all of the verticies in a std vector.
for(unsigned int stringLoop = 0; stringLoop < _buildString.length(); stringLoop++)
{
switch(_buildString.at(stringLoop))
{
case'X':
break;
case'F':
//_prevState = _currState;
_currState.position += _currState.direction * stdBranchLength;
_vertexVector.push_back(_currState.position);
break;
case'[':
_prevStack.push(_currState);
break;
case']':
_currState = _prevStack.top();
_prevStack.pop();
break;
case'-':
_currState.direction = _currState.direction.RotatedAboutZ(-(ROTATION) * Math::DegreesToRadians);
break;
case'+':
_currState.direction = _currState.direction.RotatedAboutZ(ROTATION * Math::DegreesToRadians);
break;
};
}
Now I changed my render loop so I just read straight from the vector array.
DesignPatterns::Facades::OpenGLFacade _graphics = DesignPatterns::Facades::openGLFacade::Instance();
_graphics.Begin(OGLFlags::LINE_STRIP);
for(unsigned int i = 0; i < _vertexVector.size(); i++)
{
_graphics.Vertex3f(_vertexVector.at(i).X(), _vertexVector.at(i).Y(), _vertexVector.at(i).Z());
}
_graphics.End();
Now my problem is that when I am using a vector array and I use Line Stip, I get extra artifact.
The first image is the original render that is the unoptimized one, then the second is the newer render which runs faster, and the thirds is a render of a dragon curve which uses no push and pops like the first two are using (I am pretty sure the push and pop is where the problems are coming in).
Is the problem with my logic here of storing verticies, or is it because I am using a line strip? I would just use lines, but it doesn't really work at all, it ends up looking more of a line_stipple.
Also sorry about the length of this post.
alt text http://img197.imageshack.us/img197/8030/bettera.jpg
alt text http://img23.imageshack.us/img23/3924/buggyrender.jpg
alt text http://img8.imageshack.us/img8/627/dragoncurve.jpg
You are getting those extra lines because you are using a LINE_STRIP.
In your 'F' case, push both end points of your line into the vector (like you were doing originally).
_vertexVector.push_back(_prevState.position);
_vertexVector.push_back(_currState.position);
And when you draw, use LINE_LIST instead.