I have a problem with updating the value of a class variable on each frame of gameloop.
I am using wxWidgets for creating a cross-platform window and for graphics as well as gameloop. This is my main Window
class which implements rendering and the gameloop.
#include <wx/wx.h>
#include "window.h"
#include "../entity/entity.h"
#include "../../configuration.h"
Window::Window(const wxString & title, const wxPoint & position, const wxSize & size): wxFrame(nullptr, wxID_ANY, title, position, size) {
timer = new wxTimer(this, 1);
Entity entity((width / 2) - 50, 100, 100, 100, wxColour(255, 0, 0));
AddEntity(entity);
Connect(wxEVT_PAINT, wxPaintEventHandler(Window::OnPaint));
Connect(wxEVT_TIMER, wxCommandEventHandler(Window::OnTimer));
Start();
}
void Window::Render(wxPaintEvent & event) {
wxPaintDC dc(this);
for (Entity entity : entities) {
entity.Render(dc);
}
}
void Window::Update(wxCommandEvent & event) {
for (Entity entity : entities) {
entity.Update();
}
}
void Window::AddEntity(Entity & entity) {
entities.push_back(entity);
}
void Window::OnTimer(wxCommandEvent & event) {
Update(event);
}
void Window::OnPaint(wxPaintEvent & event) {
Render(event);
}
void Window::Start() {
isStarted = true;
timer->Start(10);
}
void Window::Stop() {
isPaused = !isPaused;
if (isPaused) {
timer->Stop();
} else {
timer->Start(10);
}
}
Here is the Entity
class which represent a rectangle that can be drawn onto the window.
#include <wx/wx.h>
#include <stdlib.h>
#include "entity.h"
#include "../gravity/gravity.h"
Entity::Entity(int _x, int _y, int _width, int _height, wxColour _color) : x( _x ), y( _y ), width( _width ), height( _height ), color( _color ) {
}
void Entity::Render(wxPaintDC & dc) {
wxPen pen(color);
dc.SetPen(pen);
dc.DrawLine(x, y, x + width, y);
dc.DrawLine(x, y + height, x + width, y + height);
dc.DrawLine(x, y, x, y + height);
dc.DrawLine(x + width, y, x + width, y + height);
}
void Entity::Update() {
y += 1;
std::cout << y << std::endl;
}
On each call of the Entity::Update()
method, I want to increment the y
position and rerender the entity. However, the value of y
gets incremented only once and stays the same for the rest of the application lifetime and I can't seem to understand why. I'll be thankful for any help.
When you loop over your entities
like this (in Window::Render
, Window::Update
):
for (Entity entity : entities) {
in each iteration entity
will get a copy of the element in entities
.
In order to operate on your actual entities
via a reference you need to change it to:
//----------v---------------------
for (Entity & entity : entities) {
Another option is to use auto &
(auto
by itself does not include "reference-ness" and so will force again a copy as in your code):
//---vvvvvv---------------------
for (auto & entity : entities) {
Note that even if you only read data from your elements (and don't modify it) you can change your loop to use const &
to save the copies.