I'm working on a arduino project.
For those who don't know what a arduino is:
arduino is a little electronic-board whit a micro-controller which can be programmed in C++
Since a arduino is a little micro-controller, it is single core 16MHz multiprocessing is very hard.
I have made a class, in th constructor, it defines a pin as pwm output en sets min fade, max fade, fade time etc.
I have methods to start fading and stop fading change setpoint, speed...
for multifading I've made a update method.
So when I call light1.update() it checks if the pwm output needs to be changed or not.
Now the question is:
I have more lights so that will be:
light1.update();
light2.update();
light3.update();
and so on
Is there a way to write just one line to call update() on every object of the fade class?
Looks like you're looking for a combination of the Observer pattern combined with an Instance manager pattern.
Whenever you create a new instance of Light, add it to the manager. When you want the events to be triggered, iterate through the instances in the manager and call update.
Something like:
class LightManager
{
static std::vector<Light> lights;
static void notify()
{
for ( size_t i = 0 ; i < lights.size() ; i++ )
lights[i].update();
}
static void add(const light& l)
{
lights.push_back(l);
}
};
class Light
{
Light()
{
LightManager::add(*this);
}
};
Then you update all lights with:
LightManager::notify();
Related
Recently, I've tried to create Snake game in SFML. However, I also wanted to use some design pattern to make some good habits for future programming - it was The State Pattern. But - there is some problem that I am unable to solve.
To make everything clear, I've tried to make several Menus - one main menu, and others, like "Options", or something like this. The first option of the main menu would take the player to the "Playing State". But then, the problem appears - I think the whole game should be an independent module implemented to program. So, what should I do with the actual state which program is in? (for example, let's call this state "MainMenu").
Should I make an additional state called "PlayingState", which would represent the whole game? How would I do it? How is it possible to add new functionality to a single state? Do you have any ideas?
The State Pattern allows you, for example, to have an object of a class Game and alter its behavior when the game state changes providing the illusion that this Game object had changed its type.
As an example, imagine a game that has an initial menu and can be paused while playing if you press the space bar. When the game is paused, you can either go back to the initial menu by pressing the backspace key or continue playing by pressing the space bar again:
First, we define an abstract class, GameState:
struct GameState {
virtual GameState* handleEvent(const sf::Event&) = 0;
virtual void update(sf::Time) = 0;
virtual void render() = 0;
virtual ~GameState() = default;
};
All the state classes – i.e., MenuState, PlayingState, PausedState – will publicly derive from this GameState class. Note that handleEvent() returns a GameState *; this is for providing the transitions between the states (i.e., the next state, if a transition occurs).
Let's focus for the moment on the Game class instead. Eventually, our intention is to use the Game class as in the following way:
auto main() -> int {
Game game;
game.run();
}
That is, it has basically a run() member function that returns when the game is over. We define the Game class:
class Game {
public:
Game();
void run();
private:
sf::RenderWindow window_;
MenuState menuState_;
PausedState pausedState_;
PlayingState playingState_;
GameState *currentState_; // <-- delegate to the object pointed
};
The key point here is the currentState_ data member. At all times, currentState_ points to one of the three possible states for the game (i.e., menuState_, pausedState_, playingState_).
The run() member function relies on delegation; it delegates to the object pointed by currentState_:
void Game::run() {
sf::Clock clock;
while (window_.isOpen()) {
// handle user-input
sf::Event event;
while (window_.pollEvent(event)) {
GameState* nextState = currentState_->handleEvent(event);
if (nextState) // must change state?
currentState_ = nextState;
}
// update game world
auto deltaTime = clock.restart();
currentState_->update(deltaTime);
currentState_->render();
}
}
Game::run() calls the GameState::handleEvent(), GameState::update() and GameState::render() member functions that every concrete class that derives from GameState must override. That is, Game does not implement the logic for handling the events, updating the game state and rendering; it just delegates these responsabilities to the GameState object pointed by its data member currentState_. The illusion that Game appears to change its type when its internal state is altered is achieved through this delegation.
Now, back to the concrete states. We define the PausedState class:
class PausedState: public GameState {
public:
PausedState(MenuState& menuState, PlayingState& playingState):
menuState_(menuState), playingState_(playingState) {}
GameState* handleEvent(const sf::Event&) override;
void update(sf::Time) override;
void render() override;
private:
MenuState& menuState_;
PlayingState& playingState_;
};
PlayingState::handleEvent() must at some time return the next state to transition into, and this will correspond to either Game::menuState_ or Game::playingState_. Therefore, this implementation contains references to both MenuState and PlayingState objects; they will be set to point to Game::menuState_ and Game::playingState_ data members at PlayState's construction. Also, when the game is paused, we ideally want to render the screen corresponding to the playing state as the starting point, as we will see below.
The implementation of PauseState::update() consists of doing nothing, the game world simply remains the same:
void PausedState::update(sf::Time) { /* do nothing */ }
PausedState::handleEvent() only reacts to the events of either pressing the space bar or the backspace:
GameState* PausedState::handleEvent(const sf::Event& event) {
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space)
return &playingState_; // change to playing state
if (event.key.code == sf::Keyboard::Backspace) {
playingState_.reset(); // clear the play state
return &menuState_; // change to menu state
}
}
// remain in the current state
return nullptr; // no transition
}
PlayingState::reset() is for clearing the PlayingState to its initial state after construction as we go back to the initial menu before we start to play.
Finally, we define PausedState::render():
void PausedState::render() {
// render the PlayingState screen
playingState_.render();
// render a whole window rectangle
// ...
// write the text "Paused"
// ...
}
First, this member function renders the screen corresponding to the playing state. Then, on top of this rendered screen of the playing state, it renders a rectangle with a transparent background that fits the whole window; this way, we darken the screen. On top of this rendered rectangle, it can render something like the "Pause" text.
A stack of states
Another architecture consists of a stack of states: states stack up on top of other states. For example, the pause state will live on top of the playing state. Events are delivered from the topmost state to the bottommost, and so are states updated as well. The rendering is performed from the bottom to the top.
This variation can be considered a generalization of the case exposed above as you can always have – as a particular case – a stack that consists of just a single state object, and this case would correspond to the ordinary State Pattern.
If you are interested in learning more about this other architecture, I would recommend reading the fifth chapter of the book SFML Game Development.
For you design, i think you can use incremented loop for the different state:
Simple example:
// main loop
while (window.isOpen()) {
// I tink you can simplify this "if tree"
if (state == "MainMenu")
state = run_main_menu(/* args */);
else if (state == "Play")
state = run_game(/* args */);
// Other state here
else
// error state unknow
// exit the app
}
And when the game is running:
state run_game(/* args */)
{
// loading texture, sprite,...
// or they was passe in args
while (window.isOpen()) {
while (window.pollEvent(event)) {
// checking event for your game
}
// maybe modifying the state
// Display your game
// Going to the end game menu if the player win/loose
if (state == "End")
return run_end_menu(/* args */);
// returning the new state, certainly MainMenu
else if (state != "Play")
return state;
}
}
You have a main menu and the game, your state by default is "MainMenu".
When you enter in your main menu you click the play button, then the state returns "Play" and you go back to the main loop.
The state is "Play" so you go to the game menu and your start your game.
When the game ends, you change your state to "EndGame" and go out of the game menu to the end menu.
The end menu returns the new menu to display, so you go back to the main loop and check every available menu.
With this design you can add a new menu without changing the entire architecture.
The Situation
My company has a QML-based application which displays some content using a custom OpenGL-based render plugin (MyGame). This plugin has a few critical needs:
To be able to effect changes in the renderer in response to QML-based signals.
(e.g. change the position of an object rendered by the game)
To only process these changes at a specific spot in MyGame's redraw loop.
(This is very important; MyGame is very sensitive about when changes are allowed.)
To have the plugin redraw at 60Hz (at least).
The Problem
The code we have right now honors (1) and (2), but fails (3); the plugin does not get visually updated consistently. (The updates are erratic, at an estimated 5-10Hz.) I believe that the plugin we have created—based on QQuickFramebufferObject—is not taking proper advantage of how Qt/QML intended the scene graph to be updated.
How can I re-structure my plugin so that I get all three of the above?
The Code
Overview:
The plugin creates a QQuickFramebufferObject (MyPlugin) and a QQuickFramebufferObject::Renderer (MyRenderer).
When MyRenderer::render() is called it calls MyGame::Redraw() itself, and then calls update().
MyGame::Redraw() does what it needs to, and at the right spot where changes can be accepted, emits a timeToMakeChanges QML signal on MyPlugin.
QML listens for the onTimeToMakeChanges signal and invokes methods on the plugin that affect MyGame.
To workaround the problem of low-frequency visual updates, I've found that if I overlay a QML Canvas over my plugin and redraw the canvas frequently using a Timer, my plugin starts to get visually updated at what appears to be around 60Hz. Clearly this is a gross hack.
Following is a summary of the code setup. Please forgive missing/incorrect code; I'm trying to distill thousands of lines of glue code down to the essentials for this question.
MyPlugin.h
#include <QOpenGLFramebufferObject>
#include <QQuickFramebufferObject>
class MyPlugin : public QQuickFramebufferObject {
Q_OBJECT
public:
MyPlugin();
virtual ~MyPlugin();
virtual QQuickFramebufferObject::Renderer* createRenderer() const;
signals:
void timeToMakeChanges();
public slots:
void makeChanges(QVariant inValue);
void HandleWindowChanged(QQuickWindow *inWindow);
private:
MyGame* GetGame() { ... }
};
MyPlugin.cpp
#include "MyPlugin.h"
#include <MyGame.h>
// ******************************************************************
class MyRenderer:
public QObject,
public QQuickFramebufferObject::Renderer,
protected QOpenGLFunctions
{
Q_OBJECT
public:
virtual void render();
private:
static void RequestGameChanges();
};
void MyRenderer::render() {
if ( !m_Initialized ) {
QOpenGLFramebufferObject *theFbo = this->framebufferObject();
InitializeGl( theFbo ); // Not shown
m_MyGame = &MyGame::Create();
m_MyGame->RegisterCallback(
reinterpret_cast<qml_Function>(MyRenderer::RequestGameChanges)
);
m_Initialized = true;
}
m_MyGame->RestoreState();
m_MyGame->Redraw();
m_MyGame->SaveState();
m_PluginItem->window()->resetOpenGLState();
// Tell QML that we want to render again as soon as possible
update();
}
// This gets invoked in the middle of m_MyGame->Redraw()
void MyRenderer::RequestGameChanges() {
emit m_PluginItem->timeToMakeChanges();
}
// ******************************************************************
MyPlugin::MyPlugin() {
setMirrorVertically(true);
connect(
this, SIGNAL(windowChanged(QQuickWindow*)),
this, SLOT(HandleWindowChanged(QQuickWindow*))
);
}
void MyPlugin::HandleWindowChanged(QQuickWindow *inWindow) {
inWindow->setClearBeforeRendering(false);
}
void MyPlugin::makeChanges(QVariant inValue) {
MyGame *theGame = GetGame();
// Send the requested changes to theGame
}
QQuickFramebufferObject::Renderer* MyPlugin::createRenderer() const {
m_Renderer = new MyRenderer( *this );
}
MyApp.qml
import MyPlugin 1.0
Window {
MyPlugin {
property var queuedUpChanges: ([])
onSomeOtherSignal: queueUpChangesToMake();
onTimeToMakeChanges: makeChanges( queuedUpChanges );
}
Canvas { id:hack }
Timer {
interval:10; running:true; repeat:true
onTriggered: hack.changeWhatYouShow();
}
}
Bonus Points
The main question is "How do I modify my code so that I get 60Hz updates?" However, as seen in the QML, the setup above requires me to queue up all changes in QML so that they are able to be applied during the right spot in the MyGame::Render().
Ideally, I'd prefer to write QML without timeToMakeChanges, like:
MyPlugin {
onSomeOtherSignal: makeChanges( ... );
}
If there's a way to accomplish this (other than queuing up the changes in C++ instead)—perhaps something related to synchronize() I'd love to know about it.
I'd make a timer in QML that calls the makeChanges regularly. But store all the state in MyPlugin. Then, in Renderer::synchronize(), copy from MyPlugin to MyRenderer, so it can be used by the MyGame.
(although, I wouldn't do any gamelogic-related calculations in QML ever in the first place)
I am struggling to make my code more object orientated.
I have a small program that wishes to accomplish 2 very simple states: An input state, and a result state.
The input state seems simple to resolve as although it is graphical it is "self-updating." The user drops sprites and removes sprites on to the screen to produce an input.
The result state is annoying me because I have produced some very ugly code for it, that is not at all Object Orientated.
This state is required to do things sequentially and I am struggling to find examples of how that is done with Objects. It's basically some animation with the same object: here is some Pseudo-Code.
Static int objectx = 120, object y = 120;
Static int state=0
switch(state)
{
Case 0:
//....move object right
//....once object is far enough right
state = 1;
Case 1:
//....move object down
//....once object is far enough down
state = 2;
...etc
So I am guessing it needs to move to having some sort of state engine, but I am struggling to see how to accomplish sequential events using states. These states are always the same, and so can be hard coded, they will not change based upon the input given.
Any help will be most gratefully recieved.
UPDATE
Maybe we could think about this second state as a cut-scene in a 2d game. We want a character to walk on to the screen, say something and then walk off.
So the way I'm doing it at the moment is managing this part of the programs state via the switch statement. This function is called every time we are in the "result" part of our program, and we are using the switch statement to update the positions of our sprites. Once we have reached the end of the first set of movements we move to the next switch statement and keep doing that until it is completed. It works but I was hoping to use a " gamestate " Class, that could take ownership of the graphics and sound, and move things as appropriate.
Note: making some assumptions here because I don't have any context.
It sounds like each sprite should have its own cycle, rather than the entire game logic moving about the sprites.
Adapting this into an object-orientated design, you can wrap each sprite in some
class:
class NPC : Sprite {
private:
Position CurrentPosition;
int CurrentState;
public:
virtual void Think() = 0;
virtual void Render() = 0;
};
Then you can inherit from this class for specific sprites:
class GobbledyGook : NPC {
private:
const int FinalState = 10;
public:
bool Completed = false;
void Think() override {
if(Completed)
return;
switch(CurrentState) {
// ... repeating logic here ...
}
CurrentState++;
if(CurrentState == FinalState)
Completed = true;
}
void Render() override {
// ... draw the sprite ...
}
}
From the main game logic you can then update every sprite:
// Spawn a GobbledyGook into existence.
my_npcs.insert(new GobbledyGook());
// In frame logic.
bool finished = true;
for( NPC* n : my_npcs )
{
n->Think();
if(!n->Completed)
finished = false;
}
if(finished) {
// Result state.
}
// In render logic.
for( NPC* n : my_npcs )
{
n->Render();
}
You can naturally adopt this logic for entire scenes too:
class Intro : Cutscene {
private:
vector<NPC*> SceneSprites;
public:
void Think() override {
switch(CurrentState) {
...
}
for( NPC* n : SceneSprites ) {
n->Think();
}
}
...
};
As for whether you should be removing or changing the use of states, what do you intend to gain from doing that?
It's hard to recommend a different approach without knowing all the flaws of the current approach.
In my game I have an animated sprite. I added box2d to my game to add gravity. now I want to update my sprite's position using the schedule function. I got it working with objective-C, but I want it to be a multiplatform game so now I'm trying it in c++.
In my init I have the following line:
this->schedule(cocos2d::SEL_SCHEDULE(View::tick(1.0f)));
and the method tick:
void View::tick(float dt) {
world->Step(dt, 10, 10);
for(b2Body *b = world->GetBodyList(); b; b=b->GetNext()) {
if(b->GetUserData() != NULL) {
}
}
}
I get the following error on the line in my init: "cannot cast from type ' void' to member pointer type 'coco2d::sel_schedule' (aka void coco2d::CCobject::*)(float)
I have no idea what to do now. I tried to google, but everyone either uses objective - c or schedule_selector (which apparently doesn't work anymore)
Thanks in advance
You should probably not be using the schedule function to update a single sprite.
In your scene class, override the virtual method for update(...):
virtual void update(float dt)
{
CCLOG("This was called.");
// Do updates for everything in the scene you need to call on a tick.
}
Also, override onEnter() and onExitTransitionDidStart(). In the first, call scheduleUpdate to set up your scene for automatically being called on a tick. In the second, call unscheduledUpdate (as the scene is exiting) to stop the updates.
void IntroScene::onEnter()
{
CCScene::onEnter();
scheduleUpdate();
}
void IntroScene::onExitTransitionDidStart()
{
CCScene::onExitTransitionDidStart();
unscheduleUpdate();
}
Doing it this way gives you explicit control over what gets updated when...you only have a single function called during an update cycle.
HOWEVER, if you really want to do it:
Declare your custom updater like this:
void IntroScene::myUpdate(float dt)
{
CCLOG("Also called");
}
Schedule it like this:
schedule(schedule_selector(IntroScene::myUpdate), 1.0f);
Unschedule it like this:
unschedule(schedule_selector(IntroScene::myUpdate));
** NOTE ** As far as I know, you can only "schedule" objects derived from CCNode.
Was this helpful?
In most or all object oriented games, each class relies on not just its own but parent classes. How is this class connection implemented in C++? Do you just add a pointer for the parent class you need or is there a better way?
For example a football game, when the person class clicks it ask the scene class if he is kicking any balls, and if he is then move it. I hope this is understandable and not too abstract.
I don't think passing along the parent in a constructor is a good idea. Instead, you should be using a class that maintains a list of all game elements and facilities interactions between them; for instance, the Game class illustrated below would check for collisions between any two players and if it's detected tell each of them that they were hit and by who.
I'm not sure if this will benefit you at all, but I typed it up for my initial response so I might as well submit. Note that all of this is still relevant if you're talking about a text-only game, just ignore the allusions to graphics in that case. Game design is based around a continuous game loop, and can be thought of very simply as:
while(true)
for each tick:
react to user input
update player, enemies, objects, etc.
end while
Where "tick" is every iteration of the game clock, however you choose to implement it--based on the fps, each second, whatever. In your example, the user clicks the football, the game sees the click and tells the football to move. To do this very simply, maintain a list all of all of the game elements within a class that maintains the state. To illustrate, here are is a very basic way you could implement this:
class Game {
vector<GameElement> elements;
Football football;
Player currentPlayer;
Game() {
this.football = new Football();
}
void update() {
for e in elements:
e.update();
// Once every element has been updated for the current tick, redraw them on the screen
screen.redraw();
}
void addElement(GameElement e) {
elements.add(e);
}
}
class GameElement {
int posx, posy; // screen coordinates
void paint() {}; // method to draw this element to the screen
virtual void update();
}
class Football: public GameElement {
bool kicked;
int anglex, angley;
double velocity;
void update() {
if(kicked){
// update position, angle, velocity; slow it down, check for bounce, whatever
posx = new x position;
posy = new y position;
if(velocity == 0)
kicked = false;
}
paint(); // call the paint method after the new position has been found
}
}
Assume you have another class that inherits from GameElement, Player, with a method kick(football) that sets the passed football into motion--i.e., sets kicked=True. So to initialize the game, you'd set it up with something like:
Game game = Game();
game.add(new Football());
game.add(new Player());
while(true) {
if(user_input==X)
game.currentPlayer.kick(football);
game.update();
sleep(1);
}
This could be changed to maintain, for example, layers instead of the entire game, then a higher level class could call update of each layer in order, allowing things to be painted over each other and children to only interact with siblings. There are a lot of possibilities.
Ran into similar questions working on a poker game: Here's the way I did it:
In your example, add a scene * the_scene to the constructor of person. Then, when person is initialized pass it a pointer to scene. Since you said parent and child, if the parent Is scene then it would just use "this" and it would send the address of the parent.
Then again, it seems like that's how you were going to do it anyway. One more thing, if you need person to interact with more than one class that is not directly inside it you can make some kind of container class that would store the pointers to all of them and just pass person that one to avoid having a constructor with too many parameters.