Is there anywhere good sources where I can go and read to find out how to start to code my game so if I click a key (eg 1) that my player with cycle through his attack animation and continue to move in his current direction and only be able to attack within a certain timeframe ?
I have tried to look at other people code in games I found where the code was available but since they code with classes, it gets me confused alot as I am still learning.
I read this post https://www.allegro.cc/forums/thread/589018/634227#target. Although this kind of helps, for me it would mean putting a state within a state.
Is this possible ?
I currently have a CombatIdle state (Enemy sat idle), a Combat Chasing state (Enemy is chasing the player around) and a CombatRetreat state (Player out of range, enemy heading back to be idle). If I can put a state within a state, I'm guessing I could just put the state in the CombatChasing state as this is the one where the enemy would be in range.
I haven't posted code as I haven't began coding it. just looking for helpful resources on this before I come back and ask why it doesn't work
Cheers
...just show some code, and point out specifically what doesn't work the way you want it to....
Ok, I'm working on this now so once I get some code up and running I'll do that
Ok cool! I guess basically it's going to come down to conditions every time your game loop starts again, so, did I press attack? No? Carry on then...or...yes? Is there an enemy next to me? No? just play my attack animation then....or....yes? Well, how many DP does it have?....etc etc etc
Ok, here's what I have so far
Again my code is too long to fit it all in so cut most of it out.
So what I believe is my code is actually performing an attack animation although it is too quick for me to see. All i see if my players jumping across the screen by X pixels
This may work, however I think I need some kind of timer to slow the animation down so instead of it playing faster than I can see, it maybe takes 1-1.5 secs to complete.
This I don't know how to do.
EDIT:- If you need my full code let me know and i'll try and post it somehow
Ultimately I think you'll want a timer, but you can slow down things as well by using a 'miniCounter', that increments the frame, something like:
int miniFrame; int mainFrame; function movePlayer() { miniFrame++; if(miniFrame > 1000) //increase/decrease this to slow down/speed up { mainFrame++; } }
That way you can control when the frame count goes up by using the miniFrame counter, which can be a huge number - the only problem with this is that it wont run at the same speeds on different machines (probably), so not as precise as a timer, but it should slow things down enough to see the animation!
So what I believe is my code is actually performing an attack animation although it is too quick for me to see.
Shouldn't be the case, unless the whole animation happens in less than 16ms since it may end before the average screen can refresh.
while (keys[KEY_1] && Human.curFrame != Human.maxFrame) //Does a loop as if 1 is held down {
This loop right here will do the whole attack in one frame without doing anything.
I wrote a pretty simple way to do animation based on your already existing code. (Not tested btw, just to give an idea of the logic you can possibly use)
Fix and change as you see fit.
Cheers for the help guys.
I'm working through your code taron, trying to understand it all, but I have ran into a few issues and questions.
How do I declare or reference these within my main code ? (I've tried animation.IDLE, animation[IDLE], Animation.animation[IDLE] but none work, unless as its a struct it works differently to the way I done my enum keys[].)
I'm assuming these would be where I code my variables for different animations. I haven't done this or seen this before.
Eg if ATTACK, use animationRow 1, and animationColumns = 12
if IDLE, use animation Row 2 etc.
Then I have added this into my Player struct
However I do get the following errors
C2146: syntax error: missing ';' before identifier 'animation'
C4430: missing type specifier - int assumed.Note C++ does not support default-int
C2039: 'animation' : is not a member of 'Player'(previously all my Player struct worked) And my Player struct is in a objects.h file, if this makes any difference.
I can place this in my main body of code although this would stop PlayerAttack from working as it would no longer reference to player (I think).
I do like the way you wrote this aswell, I understand most of it can see how it works and how it does the animations
You need a ; at the end of the struct!
struct Player { Animation animation; };
I copied that from taron, didn't see his didn't have a ; at the end of the struct.
In my code I do have this at the end.
You haven't put ... in there have you??
No
My current player struct looks like this (this is working before starting to add in taron's code) I have added the Animation animation just to show how it would be
And then the error being displayed is attached
I often forget to put a ';' after classes and structs if I recently programmed in a different language.
How do I declare or reference these within my main code ? (I've tried animation.IDLE, animation[IDLE], Animation.animation[IDLE] but none work
Animation::IDLE would be the correct syntax.
Also you'd have to add int animationState or something inside the Animation struct to track which animation is being played, I forgot to add that.
C2146: syntax error: missing ';' before identifier 'animation'
C4430: missing type specifier - int assumed.Note C++ does not support default-int
Generally this means it doesn't recognize the type. If you've put the Animation in its own header file, make sure to include that header in your Player header, otherwise the compiler will not be able to find the definition of the type.
If you've defined the Animation in your main.cpp or whatever file, move it to a header file.
So it would look something like this:
#ifndef PLAYER_H #define PLAYER_H #include "animation.h" struct Player { ... }; #endif
Or the shorter but less portable way. (Non standard extension, but supported by many compilers)
#pragma once #include "animation.h" struct Player { ... };
Yeah the code is fine, have you declared Animation before player?
Nope, I had declared Animation after it, changed it and that's fixed that part, thanks Dizzy.
Taron, thanks for the help on the correct syntax, now to work on getting it right, not long left to finish it
All my structs are in the same file, I only have 2 objects.h (all my structs) and main.cpp
Hopefully I should be able to figure this out now.
Cool! Let us know if you get stuck again....I'm warming up for Speedhack so need motivation to get coding Allegro5 again!
I think i'm doing this wrong :-(
I have placed my ChangeAnimation in my ALLEGRO_EVENT_TIMER code, so to me it says, if Player is in the CombatIdle state and KEY_1 is pressed then change the animation.
Then for the function I have placed some states of the animations.
What would go in place of newAnimation in this line ChangeAnimation(animation, newAnimation); ?
I tried Animation::ATTACK, animation::ATTACK, animation.ATTACK with no luck.
Before you use 'newAnimation', do you create it?
ie:
Animation *newAnimation; ChangeAnimation(animation, newAnimation);
(the above code wont work, I was just seeing if you'd 'created' the newAnimation...)
EDIT:
Consider this...
int i = 5; void changeInt(int &arg) { arg = 20; } int main() { changeInt(i); //i now = 20!! }
That will be it, no I haven't created it apart from in the ChangeAnimation function. I see that part is in the PlayerAttack part of tarons code.
I feel i'm getting more and more confused as I delve further into the depths of the unknown :-) And going from zero Allegro5 experience to doing it alot everyday is also confusing me.
Cheers Dizzy :-)
Try not to go too far down a road that is suggested on here if it seems alien; I used 1 .cpp file and hundreds of separate variables for my first 20 odd projects....LONG before I started delving into enums and structs....keep it simple, and as soon as something doesn't make sense, come on here and post some code...that's how I learned!
Cheers for the advice.
So trying to do it in a way I understand. Using Mike Geig's tutorial on his spaceshooter he has a comet going across his screen using no input. It move across without any keys being involved and his code for that is
I added comments to compare to my code.
So based on that, I want a animation to happen basically the same way except I press a key first so I press the key and declare that the player is attacking
So looking at the 2 codes, why is one allowing it to be cycled all the time and perform the animation across the screen, yet with my code only cycle through the animation when I actually hold down the key. From what I gather I have removed the keypress part by adding the PlayerAttacking, so my PlayerAttacking is now similar to If the comet is onscreen.
The only big difference I see is
My code
Mike Geig's code
We both have our calls in the ALLEGRO_EVENT_TIMER section aswell.
EDIT_ OMG I got it to work
On the bad side is when I move after attacking it plays that animation again, but I got it to work
So...do you want your animation run whilst you're holding down KEY_1, or simply run it when KEY_1 is pressed?
EDIT!
YOU GOT IT!
I just edited at the same time but I kinda got it to work
I just wanted my player to move about, but if the 1 key was pressed (and released) it would play a attack animation.
As of now when I press 1 it does plays the attack animation
However when I move after that it keeps playing the attack animation instead of the moving ones. So need to fix that
But it is progress
Cool
EDIT:
Human.Attacking = true; if (Human.Attacking) // Is my player attacking, then do the code below
..hmmmmm
You right
I changed to this
Where before I was doing
Then putting Human.Attacking = true; in my function.
It was probably suggested way earlier than now I just didn't get it in the right place
EDIT:- If press 1 while moving he plays his attack animation all the time, until i release left or right and repress it
I imagine there's some confusery in your event keydown if/else type code! If you like you can post a whole bunch of code here, it seems we're getting on ok! I can do no more tonight as I am inebriated, but tomorrow I will be able to quest on with you, we'll figure it out bro
My key events are as follows:-
You are checking against true in both cases, which will always evaluate to true.
See my response to you in an earlier thread :
https://www.allegro.cc/forums/thread/615373/1013171#target
For example, here you should have used this :
if (true == canPressKeyC) {
or this :
if (canPressKeyC) {
instead of this :
if (true = canPressKeyC) {(which would have given you an error)
or this :
if (canPressKeyC = true) {(which always performs an assignment and evaluates to true)
So a == rather than a single =
Ok i'll get that changed now. I did read that, didn't fully understand what was being discussed, I was happy that it started working and then started working on another area.
Thanks Edgar
See
Animation::IDLE would be the correct syntax.
Also you'd have to add int animationState or something inside the Animation struct to track which animation is being played, I forgot to add that.
So you can/could do
animationState = Animation::IDLE; ...
switch (animationState) { case Animation::IDLE: ... break; case Animation::MOVE: ... break; } // or if (animationState == Animation::IDLE) { ... }
Enums are actually quite simple.
Much like structs, unions and classes you can also give them a name instead of making them anonymous.
If you want to make use of enums in new code, you should probably default to using enum class instead of simply enum.
@Edgar
For example, here you should have used this :
<if (true == canPressKeyC) {
or this :
if (canPressKeyC) {
This didn't work for me after I made the change, so i reverted back to the original as that is working as intended, not sure why but it is working.
@Taron
What I think I will do rather than trying to re-work my code at this stage, is that once I'm done, I'll start a fresh project only using code for the enum/structs for the animation and play about with it there, I would like to try and get that working.