I'm currently coding a version of breakout as a quick learning experience of C and OpenGL.
Im having some issues with moving the paddle. I've set a keyboard callback so that when the left arrow is pressed, it subtracts 1 from the x value on the paddle, and adds 1 to the x value when pressing the right arrow.
With this in mind, the paddle moves incredibly slow when I hold either key. I can change this by increasing the amount the x value is changed to 10 for example. When I do this the paddle seems to stutter across the screen because it's jumping 10 at a time. It does of course move faster along the screen now but doesn't look smooth.
I'm using GLUT for windowing on OSX.
Is there a way of speeding this up and keeping it looking smooth?
A common thing in games is a keyboard array. Therefore you will be also able to press several buttons at a time.
You have an array where you keep state of keys (you put 1 when you get pressed, set 0 when released). And you process game in each frame by taking information just from array, not directly from input.
Here is some code from one of my projects:
bool keyDown[256];
...
//Called when a key is pressed
void handleKeypress(unsigned char key, int x, int y) {
keyDown[key] = true;
}
void handleKeyUp(unsigned char key, int x, int y){
keyDown[key] = false;
}
This essentially keeps an array of the states of each key, so you can just check them each time. Then you don't have to depend on the callbacks coming in that frequently.
Related
I'm writing a simple game in C with SDL and I have defined that player one controls it's_for example_tank with arrow key of the keyboard and player two controls it's tank with the keys "W","A","S","D" of the key board.
My problem is they can't press the keys simultaneously.
I have a function called "handle_events" that controls the events in the infinite while of the game and it's code is like below:
int handle_events(Tank* tank,Tank* tanker, Wall walls[]){
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
return EXIT;
if (event.type == SDL_KEYDOWN){
if(event.key.keysym.sym==SDLK_UP){
move_tank_forward(tank,colliding(tank,walls));
}else if(event.key.keysym.sym==SDLK_DOWN){
move_tank_back(tank,colliding(tank,walls));
} else if(event.key.keysym.sym==SDLK_RIGHT || event.key.keysym.sym==SDLK_LEFT) {
turn_tank(event.key.keysym.sym, tank);
} else if(event.key.keysym.sym==SDLK_w){
move_tank_forward(tanker,colliding(tanker,walls));
} else if (event.key.keysym.sym==SDLK_s){
move_tank_back(tanker,colliding(tanker,walls));
} else if(event.key.keysym.sym==SDLK_d || event.key.keysym.sym==SDLK_a){
turn_tank(event.key.keysym.sym, tanker);
}
}
I'm looking for a way that two players can play simultaneously because right now if for example both players press the up key and the w key, none of them can move their tank.
It appears you rely on key repeat - feature of operating/windowing system to repeat last pressed key with fixed interval after some initial pause, e.g. when you keep key pressed in text editor it starts filling that symbol after some delay. Only last key is repeated though.
With SDL, you should know when key is repeated from repeat field of keyboard event. However, you almost never want to make prolonged movement based on keypress event. With your current scheme, I can press a key very quickly and tank will move faster, or I can modify my OS repeat interval. Movement, if supposed to be at constant speed, should rely on time, not how fast user can press a button. That is why you only need to take nothion of "ok, button A pressed, - as long as it pressed, I will attempt to rotate left at each fixed update interval", and when you get key-released event - you drop that intention.
As Danny_ds said, it is often much easier and robust to use key state array instead of events (mostly because of repeat) - with SDL, you can get that via SDL_GetKeyboardState. Make your update_movements or whatever function, and call it every N miliseconds.
On Windows you can use the GetAsyncKeyState() function.
For an equivalent on Linux see this question.
Here's my dilemma
I have 4 walls around the stage of my game, when a player hits these walls I do not want to make an if statement for each and every one of the walls checking if the player is hitting it, so I have created an array to hold the walls, then check if the player is hitting that. Now, because I am doing this I will not know what the player is actually hitting if he hits something, and I cannot do a check in my array if he's hitting like [0], [1], [2] etc because then I'm back to doing the checks if he's hitting specific walls. The reason I don't want to do that is for the future, when I add more barriers, buildings, and so on.
So my question is, how can I do collision checks, without hard coding checks on specific objects, and giving some sort of value that can be used for the player to respond to, for example if your hitting the top wall and you can figure that out somehow without doing the above, then make it so you can't walk through or something,
if (main.playerPosKeeper_mc.hitTestObject(this[main.StageCollisions]))
{
trace("hit");
}
StageCollisions is an array which contains all of my barriers in it.
When the player hits anything in StageCollisions, I cannot just simply subtract from his y value, or x value, because I do not know which object he hit, but I also do not want to hard code it so that I check if I'm hitting lets say the top barrier, because then why do an array in the first place if I'm just going back to making static if else statements.
^^ Refrencing this topic
AS3 - How to Cycle States of Character Animations (moving & stopped)
This has been stumping me for a little while, so help would be greatly appreciated. It is a hard question to form so I can clarify points if necessary.
So my question is, how can I do collision checks, without hard coding
checks on specific objects, and giving some sort of value that can be
used for the player to respond to, for example if your hitting the top
wall and you can figure that out somehow without doing the above, then
make it so you can't walk through or something
Right, so you want a way to perform a generic collision response. This can be a big topic. The simplest approach is usually to check for a collision after a move, then reverse the move if there's a collision.
Something like this:
function movePlayer(movementX:Number, movementY:Number):void {
var originalX:Number = player.x;
var originalY:Number = player.y;
player.x += movementX;
if (checkCollision()) {
player.x = originalX;
}
player.y += movementY;
if (checkCollision()) {
player.y = originalY;
}
}
function checkCollision():Boolean {
for each (var wall:MovieClip in walls) {
if (player.hitTestObject(wall)) {
return true;
}
}
return false;
}
This way you could have checkCollision() check 4 walls or 50 walls, it doesn't matter. It won't let the player move into them.
This is just a starting point and there are many ways it can break down or be refined.
Some trivial pseudo code for you to study:
private function collisionCheck(h:Sprite):Sprite{ // pass the hero Sprite into this function and it will return the wall that it hit
for each (b:Sprite in blockArray){ // if your array of hit-able objects is called "blockArray"
if (h.hitTtestObject(b)){ // check the hero Sprite against all objects in the array
return b;
}
}
return null;
}
Then, elsewhere in your code (maybe in your gameTick function or gameLoop function or wherever you have your game logic repeating on each frame:
private function gameTick():void{
var objectHit:Sprite = collisionCheck(_myHero); // this will run the collision check function, and return the sprite that the hero collides with;
if (objectHit != null){
objectHit.alpha = 0.5;
// this will give you a visible representation that your code is indeed working, or not.
}
}
For those moments when your hero isn't colliding with anything, this function will return null. That's why I first check if objectHit is not null before trying to perform an operation on its alpha value. Of course, you will do something other than change its alpha value in your project, but this is something I often do (with the alpha) to quickly get a visual confirmation that things are detecting what they are supposed to.
I'm programming now a snake program. I have a little problem in the movement. My direction buttons are the 'W' 'A' 'S' 'D' buttons.
I have a direction variable, wich type is char. I read a button from keyboard, direction gets a value, and the snake makes one step from the 4 directions, if I hit one from WASD and then enter. I'd like to fix the enter problem.
I want, that my snake moves continually, and doesn't wait for the enter.
I'd like to make a timer for direction that way, if I don't hit a character in X milliseconds, then the snake continues to move in the direction of the last value of direction.
How to make this timer? Or any other idea?
It depends on the language you are programming in :-).
Eg. if you have a sleep() or delay() function available, you don't need any special timers and a simple infinite loop will do the job.
The important thing is how you are reading the keyboard. You can read buttons as they are pressed (non-blocking) or waiting for them till they are pressed (blocking). In your case you are reading whole lines - this is why it waits for the enter.
Not sure what is your programming language, but this pseudo-code could explain it a bit. The keyPressed() and readKey() are some fictive library function, which you need to find in your language.
while (true) {
if (keyPressed()) {
direction = readKey();
}
move(direction);
sleep(1);
}
Unfortunately, without knowing the language and if an SDK like SDL, XNA, Monogame, etc. are used we can't help. I would suggest trying to search for handling keyboard events. In XNA while the game is running it calls Draw, Update, and Event. Usually the keyboard event would be handled like so:
//...
public void Update()
{
if(Keyboard.GetStates().IsKeyDown(Keys.W))
{
Player.ChangeDirection(Direction.UP);
}
//...
Player.Move();
}
Player.ChangeDirection(Direction) may will change how the snake moves. The movement is done in the Player.Move() command every time.
EDIT: In C++ are you using any SDKs like SDL, Allegro, DirectX or that?
I'm coding a console editor in C. I'm using CodeLite Editor on Windows. I want to insert a newline ('\n') when the user presses Return (Enter) key. I want to accomplish this goal with getchar() function is that possible?
I need it because I want to increment the y axis variable.
Code I'm trying on :
int X = 0; // X-axis
int Y = 0; // Y-axis
char key = getchar();
if (key=='sth') // Here I want to perform my check
{
//Do Something
++Y;
}
Update :
If it has a code like : '\x45' for example post it in the comments plz!!!
If you are trying to implement an editor, you will quickly find that getchar() is not the way to interpret keyboard events. In this very simplistic example, where all you might do is wait for a single keystroke of input that either is or is not a newline, your program will work if you change 'sth' (an abbreviation for "something"?) to '\n'. However, as your editor becomes more complicated, you will want to have an actual event handler that can detect any sort of keyboard events and can asynchronously deal with them. getchar() is not the way to do that.
This answer from 7 years ago shows that (1) you can go a limited distance with getch() (and getchar()), but (2) a far larger number of people agree that it's no substitute for a real event handler: Detect Keyboard Event in C
So I'm making this text based game for my 'C' Programming class.
I want to continue it even after I'm done with the class so it's not just a homework assignment I want to actually keep it for later use.
My question is in this part of the code is there a way to send the user back to the previous question asked when using an 'IF' statement so they can make multiple choices before ultimately going the direction of the story?
if (door2 == 1)
{
// what happens when you touch the orb.
printf("The orb transports you to an unknown location.\n");
printf("You look around to get the lay of your area,\n");
printf("off in the distance you see a church like building.");
door2 = door2 - 1;
printf("\n");
printf("Do you go to the building? ");
scanf_s("%d", &door1);
printf("\n");
if (door1 == 1)
{
// Going up to the church.
printf("You walk up to the building, it gives you a strange feeling\n");
printf("in the pit of your stomach. You look around and see two windows\n");
printf("low enough for you to see into along with the main door.\n");
printf("Do you go to the left window? right window? or try to open the front door?\n");
scanf_s("%d", &movement);
printf("\n");
if (movement = 1)
{
// left window.
printf("You creep up to the window and peak inside...\n");
printf("You see a large figure pacing back and forth in the room\n");
printf("what ever it is spots you and darts further into the church.");
movement = movement - 1;
// i subtract the L,S,R numbers to insure there is not an infinite loop.
}
else if (movement = 2)
{
// front door.
printf("You walk up to the front door, and try to open it.\n");
printf("The door does not budge, it must be locked.");
movement = movement - 2;
}
else if (movement = 3)
{
// right window.
printf("You creep up to the window and find an empty room.\n");
movement = movement - 3;
printf("The window is cracked open somewhat... Do you try to enter the\n");
printf("church through the window? ");
scanf_s("%d", &door2);
printf("\n");
}
Actually yes, if you would just put a loop around that, but i'd advise splitting your ifs in functions. Your code will look much better.
void main() {
enterTheCurch();
}
void enterTheCurch() {
printf("You've entered the Curch. There are 2 Doors. Do you want to go left or right?");
String direction;
scanf_s("%s", &direction);
if(direction == "left") {
goLeftCurchDoor();
}
else {
goRightCurchDoor();
}
}
goLeftCurchDoor() {
...
}
goRightCurchDoor() {
...
}
Try using this structure. Like this you also can give parameters to the function like bool alreadyVisited and change the prints depending on these parameters.
This is probably not the correct approach at all. A game generally is split into several components: a main loop (that runs infinitely), an update loop (that simulates the game world) and a process input function (which takes input from the user.)
The way your code is structured also leaves much to be desired. For one thing, your prompts to the user are inconsistent. Sometimes you seem to be asking a yes or no question, other times it seems you want a movement command with no indication to the user which is expected. This is a UX nightmare. Instead, you can treat each movement as an action. For example, going forward to a locked door means the user wants to try to open the door. Going forward with an open window means the user wants to travel through the window. With that in mind, it becomes clear that you only actually need to keep track of one variable.
Making a game is not an easy task and you cannot brute force your way into making one - it requires thoughtful planning ahead of time. Try drawing a dialogue tree on a piece of paper. You'll quickly see it spiral out of control as you run out of room on the paper - designing a game is a complex task. It's important to have a blueprint before you begin coding.
First, let's tackle what your game loop can look like:
#include <stdio.h>
#include <stdbool.h> // for true and false
typedef enum { NONE = 0, LEFT, RIGHT, UP, DOWN } movement_t;
int main()
{
movement_t movement = NONE;
movement_t last_movement = NONE;
while (true)
{
int movement_input = 0;
scanf("%d", &movement_input);
movement = (movement_t) movement_input;
// ...
last_movement = movement;
}
}
Now you want to know what kind of data structure should represent your game. Unfortunately this is a complex topic and I'm not a game developer, so I'll try to present a naive approach. The simplest way that takes less work is to have a static message for each room as you enter it. If something changes, then you could reflect that change once a variable has been updated.
void church()
{
printf("Generic church description.");
if (some_player_did_something)
{
printf("You now spot a shiny object on the floor.");
}
}
Keeping track of the player's last movement (which I have demonstrated above) is useful for determining where they came from.
if (last_movement == LEFT)
{
printf("You come in from the left and noticed something you haven't before...");
}
I would take the suggestions from the others and split your code into functions (as I'm sure your instructor has drilled into you by now.) A monolithic approach is not the way to go.
There is one: goto.
label:
if (someCondition) {
goto label;
}
This code will loop until someCondition becomes false.
goto is a inconditional jump, and allow you to jump excecution forward or backward to a label, provided you stay in the same scope.
Lots of people hates goto, and you should make sure not to use it if you have other better alternatives.
Story telling sounds like a nice use case for goto.
Loops or recursion are other options to produce this result, such as while do ... while for.
each location in the game needs an entry in a table,
along with certain environment details such as:
which direction is the player facing
visible items at each location
current game state,
current inventory,
'next' table entry to use, etc.
This table grows huge very quickly and can have many parameters per line in the table. It is the actual game. All the rest is just user manipulation of the table, current conditions, etc.
Every possible user input has a unique function to handle that input (there are not that many possible inputs).
Each of these functions gets a parameter that is a pointer to an entry in the location table, that lets that function process the user input.
The main loop of the program handles getting input from the user and dispatching the appropriate inputFunction handler.
There will be sub functions to handle inventory changes, display inventory, enable/disable certain types of actions, etc