I am not that familiar with c++ lists, so hopefully someone else will answer your question. I am learning c++ myself so I hope if I made any mistakes someone will point them out.
[QUOTE=Samuka97;25840085][cpp]Bullet::~Bullet () {
delete x;
delete y;
delete speed;
delete direction;
delete color_r;
delete color_g;
delete color_b;
delete color_a;
}[/cpp][/QUOTE]
None of those variables are pointers, so they don't need to be, and in fact can't be, used with the "delete" keyword. Their existence is inherently tied to that of the Bullet that contains them.
[QUOTE=Samuka97;25840309]Okay... so what now? I'm still lost on how I can create, update and delete bullets without using an array.
[editline]4th November 2010[/editline]
Already got bullet.h, had bullet.cpp but it didn't have anything in it. Going to do this tomorrow, got some school work now.[/QUOTE]
[cpp]
#include "Bullet.h" // Or whatever
std::list<Bullet> bullets;
// To create
int create_bullet(int bullet_count, double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a)
{
Bullet temp_Bullet(x, y, speed, direction, color_r, int color_g, int color_b, int color_a); // Create a temp
bullets.push_back(temp_Bullet); // Add to the list
return 0; // Yayifications, all went well.
}
// To update
int update_bullets()
{
for(int i; i < bullets.size(); i++) // Go through all of them until you reach the end of the list
bullets[i].update(); // Define update() in your bullet class
return 0;
}
// To delete
int delete_bullets()
{
for(int i; i < bullets.size(); i++)
{
if(bullets[i].x > screen_x || bullets[i].x < 0 || bullets[i].y > screen_y || bullets[i].y < 0) // If offscreen
{
bullets.remove(i); // Remove the bullet
}
else if(/* Other reasons to delete bullets, idk*/)
{
bullets.remove(i);
}
}
return 0;
}
[/cpp]
Pretty sure this is okay...? :raise: If you call update_bullets() and delete_bullets() in your game loop it should all be fine, obviously you need to make Bullet.update() change the bullet positions etc. etc. first.
[QUOTE=Wyzard;25839888]That being said, though, there's no difference in how they're stored in a list. You can make a std::list of a struct type just like you can make one of a class type.[/QUOTE]
In fact, the only differences between a class and a struct are the default visibility.
[QUOTE=Liquid Helium;25840246]Yes, although there is no need for the deconstructor as the garbage collector will do all that for you.[/QUOTE]
That's not garbage collection, that's just automatic stack management.
[QUOTE=BlkDucky;25842384][cpp]
#include "Bullet.h" // Or whatever
std::list<Bullet> bullets;
// To create
int create_bullet(int bullet_count, double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a)
{
Bullet temp_Bullet(x, y, speed, direction, color_r, int color_g, int color_b, int color_a); // Create a temp
bullets.push_back(temp_Bullet); // Add to the list
return 0; // Yayifications, all went well.
}
// To update
int update_bullets()
{
for(int i; i < bullets.size(); i++) // Go through all of them until you reach the end of the list
bullets[i].update(); // Define update() in your bullet class
return 0;
}
// To delete
int delete_bullets()
{
for(int i; i < bullets.size(); i++)
{
if(bullets[i].x > screen_x || bullets[i].x < 0 || bullets[i].y > screen_y || bullets[i].y < 0) // If offscreen
{
bullets.remove(i); // Remove the bullet
}
else if(/* Other reasons to delete bullets, idk*/)
{
bullets.remove(i);
}
}
return 0;
}
[/cpp]
Pretty sure this is okay...? :raise: If you call update_bullets() and delete_bullets() in your game loop it should all be fine, obviously you need to make Bullet.update() change the bullet positions etc. etc. first.[/QUOTE]
It'd be more efficient to use iterators, since using an index requires random access which for lists is slower.
Instead of delete_bullets 'd rather call it delete_obsolete_bullets or something.
bullet.h
[cpp]class Bullet {
public:
double x, y, speed, direction;
int color_r, color_g, color_b, color_a;
int update()
}
int Bullet::update() {
// Color the bullet
BulletSpr.SetColor(sf::Color(color_r, color_g, color_b, color_a));
// Calculate it's trajectory
x = x + speed * cos(direction*pi/180);
y = y - speed * sin(direction*pi/180);
// Move it's sprite
BulletSpr.SetPosition(float(x), float(y));
BulletBackSpr.SetPosition(float(x), float(y));
// And finally, draw it.
App.Draw(BulletBackSpr);
App.Draw(BulletSpr);
}[/cpp]
bullet.cpp
[cpp]#inlcude "Bullet.h"
Bullet::Bullet (double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a) {
x = x;
y = y;
speed = speed;
direction = direction;
color_r = color_r;
color_g = color_g;
color_b = color_b;
color_a = color_a;
}
Bullet::~Bullet () {
}[/cpp]
main.cpp
[cpp]std::list<Bullet> bullets;
int create_bullet(double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a)
{
Bullet temp_Bullet(x, y, speed, direction, color_r, int color_g, int color_b, int color_a); // Create a temp bullet
bullets.push_back(temp_Bullet); // Add it to the list
return 1; // We managed to create the bullet! Yay!
}
[rest of the source, etc][/cpp]
But now, how do I change this:
[cpp]for(std::list<int>::iterator iter = bullets.begin(); iter != bullets.end(); ++iter) //an iterator is for .. iterating over the elements :)
{
std::cout << *iter << '\n'; //using the unary * on an iterator 'dereferences' it, meaning that it returns the value of the current place we are iterating over
//if you already know pointers, an iterator has some similarities to that
}[/cpp]
to get the elements from the bullet struct?
[editline]4th November 2010[/editline]
also if there's something wrong with my code, can someone please point it out?
Not neccesarily wrong, but the update-function should probably go in the bullet.cpp file.
Then you need header guards. Basically, in your .h files
[cpp]#ifndef SOME_UNIQUE_NAME //usually something like FILE_NAME_H
#define SOME_UNIQUE_NAME
//code stuffs here
#endif[/cpp]
You can quickly read up on them to understand why and how this works.
Then I'd choose .hpp instead of .h out of aesthetic reasons (.h accompanies .c files for C-stuff, .hpp accompanies .cpp for C++-stuff).
Now for your problems:
You only defined the constructor and destructor, but you didn't declare it in the class definition:
A declaration is the prototype without the body.
You forgot a ; after 'update()' in bullet.h.
main.cpp looks about right. Look for a boolean-type instead of int for this function, since it'd fit better.
The for-loop just needs a std::list<Bullet>::iterator instead of a std::list<int>::iterator ;)
Oh, and ofcourse you don't wanna output the bullet, but call update on it via iter->update();.
[b]main.cpp[/b]
[cpp]std::list<Bullet> bullets;
bool create_bullet(double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a)
{
Bullet temp_Bullet(x, y, speed, direction, color_r, color_g, color_b, color_a); // Create a temp bullet
bullets.push_back(temp_Bullet); // Add it to the list
return true; // We managed to create the bullet! Yay!
}
bool update_bullets()
{
for(std::list<Bullet>::iterator iter = bullets.begin(); iter != bullets.end(); ++iter) //an iterator is for .. iterating over the elements :)
{
// Update the bullets.
iter->update();
}
}[/cpp]
[b]bullet.hpp[/b]
[cpp]#ifndef BULLET_H //usually something like FILE_NAME_H
#define BULLET_H
#pragma once
//---------------------------------------------------------------------------
class Bullet {
public:
double x, y, speed, direction;
int color_r, color_g, color_b, color_a;
void update();
Bullet (double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a);
~Bullet();
};
//---------------------------------------------------------------------------
#endif[/cpp]
[b]bullet.cpp[/b]
[cpp]#include "Bullet.hpp"
Bullet::Bullet (double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a) {
x = x;
y = y;
speed = speed;
direction = direction;
color_r = color_r;
color_g = color_g;
color_b = color_b;
color_a = color_a;
}
Bullet::~Bullet () {
}
void Bullet::update() {
// Color the bullet
BulletSpr.SetColor(sf::Color(color_r, color_g, color_b, color_a));
// Calculate it's trajectory
x = x + speed * cos(direction*pi/180);
y = y - speed * sin(direction*pi/180);
// Move it's sprite
BulletSpr.SetPosition(float(x), float(y));
BulletBackSpr.SetPosition(float(x), float(y));
// And finally, draw it.
App.Draw(BulletBackSpr);
App.Draw(BulletSpr);
}[/cpp]
-------
Error:
[code]1>Compiling...
1>Bullet.cpp
1>.\Bullet.cpp(19) : error C2065: 'BulletSpr' : undeclared identifier
1>.\Bullet.cpp(19) : error C2228: left of '.SetColor' must have class/struct/union
1> type is ''unknown-type''
1>.\Bullet.cpp(19) : error C2653: 'sf' : is not a class or namespace name
1>.\Bullet.cpp(19) : error C3861: 'Color': identifier not found
1>.\Bullet.cpp(22) : error C2065: 'pi' : undeclared identifier
1>.\Bullet.cpp(22) : error C3861: 'cos': identifier not found
1>.\Bullet.cpp(23) : error C2065: 'pi' : undeclared identifier
1>.\Bullet.cpp(23) : error C3861: 'sin': identifier not found
1>.\Bullet.cpp(26) : error C2065: 'BulletSpr' : undeclared identifier
1>.\Bullet.cpp(26) : error C2228: left of '.SetPosition' must have class/struct/union
1> type is ''unknown-type''
1>.\Bullet.cpp(27) : error C2065: 'BulletBackSpr' : undeclared identifier
1>.\Bullet.cpp(27) : error C2228: left of '.SetPosition' must have class/struct/union
1> type is ''unknown-type''
1>.\Bullet.cpp(30) : error C2065: 'App' : undeclared identifier
1>.\Bullet.cpp(30) : error C2228: left of '.Draw' must have class/struct/union
1> type is ''unknown-type''
1>.\Bullet.cpp(30) : error C2065: 'BulletBackSpr' : undeclared identifier
1>.\Bullet.cpp(31) : error C2065: 'App' : undeclared identifier
1>.\Bullet.cpp(31) : error C2228: left of '.Draw' must have class/struct/union
1> type is ''unknown-type''
1>.\Bullet.cpp(31) : error C2065: 'BulletSpr' : undeclared identifier[/code]
Damn.
[editline]4th November 2010[/editline]
I guess this is why I shoved everything in main.cpp?
[QUOTE=Samuka97]learnings[/QUOTE]
God damn, you're doing well for being taught by a consortium of teachers.
Not meaning to be overly critical, but there's such a thing as too many cooks.
Maybe you guys could lay off on the semantics?
"Permission settings" don't really matter at this stage in a student's learning, and perhaps explain [i]why[/i] [b]delete[/b] can't be used on those variables (and so on).
Permission settings? You mean visibility (public, protected, private)?
And I'd not think it's necessary to tell why not to delete stuff; s/he'll learn that upon learning heap memory.
Anyways, BulletSpr is clearly not defined anywhere. Neither is BulletBackSpr. You might have it as a global in main.cpp, but you should have an instance of it in the Bullet struct and thus have a sprite per bullet.
The code is also complaining about sin and cos because you did not include the appropriate header (cmath), in which it is declared.
[editline]4th November 2010[/editline]
Oh, and about App you should probably pass that as a reference.
[QUOTE=ZeekyHBomb;25849384]Not neccesarily wrong, but the update-function should probably go in the bullet.cpp file.[/QUOTE]
Personally, I tend to put major methods in their own file. So, Bullet.update() would have it's own file called Bullet_update.cpp or something along those lines. Means Bullet.cpp doesn't get too cluttered. If they're just small methods, I group relevant methods together in a file.
[QUOTE=ZeekyHBomb;25851008][...] Oh, and about App you should probably pass that as a reference.[/QUOTE]
...how exactly?
[b]Edit:[/b] Also isn't loading the same 2 sprites for each bullet going to slow the game a lot? Because in SFML, you load the image, then make the sprite, but I'm going to need to do both for each bullet I think...
No, you keep one image and make multiple sprites out of it. The image-data stays with the image, while the sprite just references the image.
Read up on C++ references :P (not to be confused with a C++ reference, which would be a reference for the C++ language and not a datatype called reference)
Can't, it then complains about BulletImage being non-existant. Am I missing something very [b]very[/b] obvious?
I could only guess that it's in a different scope.
Code?
bullet.hpp
[cpp]#ifndef BULLET_H //usually something like FILE_NAME_H
#define BULLET_H
#pragma once
//---------------------------------------------------------------------------
class Bullet {
public:
double x, y, speed, direction;
int color_r, color_g, color_b, color_a;
void update();
Bullet (double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a);
~Bullet();
};
//---------------------------------------------------------------------------
#endif
[/cpp]
bullet.cpp
[cpp]#include "Bullet.hpp"
#include <cmath>
#include <SFML/Graphics.hpp>
const double pi = 3.1415;
Bullet::Bullet (double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a) {
x = x;
y = y;
speed = speed;
direction = direction;
color_r = color_r;
color_g = color_g;
color_b = color_b;
color_a = color_a;
}
Bullet::~Bullet () {
}
void Bullet::update() {
//sf::Image BulletImage;
//sf::Image BulletBackImage;
//BulletImage.LoadFromFile("data/gfx/bullet1.png");
//BulletBackImage.LoadFromFile("data/gfx/bullet1_back.png");
// Create a sprite for the player image.
sf::Sprite BulletSpr(BulletImage);
sf::Sprite BulletBackSpr(BulletBackImage);
// Set up some properties for it.
BulletSpr.SetCenter(14.f, 14.f);
BulletBackSpr.SetCenter(8.f, 8.f);
// Color the bullet
BulletSpr.SetColor(sf::Color(color_r, color_g, color_b, color_a));
// Calculate it's trajectory
x = x + speed * cos(direction*pi/180);
y = y - speed * sin(direction*pi/180);
// Move it's sprite
BulletSpr.SetPosition(float(x), float(y));
BulletBackSpr.SetPosition(float(x), float(y));
// And finally, draw it.
App.Draw(BulletBackSpr);
App.Draw(BulletSpr);
}
[/cpp]
main.cpp
[cpp]////////////////////////////////////////////////////////////
// Custom Functions
////////////////////////////////////////////////////////////
std::list<Bullet> bullets;
bool create_bullet(double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a)
{
Bullet temp_Bullet(x, y, speed, direction, color_r, color_g, color_b, color_a); // Create a temp bullet
bullets.push_back(temp_Bullet); // Add it to the list
return true; // We managed to create the bullet! Yay!
}
void update_bullets()
{
for(std::list<Bullet>::iterator iter = bullets.begin(); iter != bullets.end(); ++iter)
{
// Update the bullets.
iter->update();
}
}
[/cpp]
error
[code]1>Compiling...
1>Bullet.cpp
1>.\Bullet.cpp(28) : error C2065: 'BulletImage' : undeclared identifier
1>.\Bullet.cpp(29) : error C2065: 'BulletBackImage' : undeclared identifier
1>.\Bullet.cpp(47) : error C2065: 'App' : undeclared identifier
1>.\Bullet.cpp(47) : error C2228: left of '.Draw' must have class/struct/union
1> type is ''unknown-type''
1>.\Bullet.cpp(48) : error C2065: 'App' : undeclared identifier
1>.\Bullet.cpp(48) : error C2228: left of '.Draw' must have class/struct/union
1> type is ''unknown-type''[/code]
this is sure great
I don't mean to be rude, but maybe instead of posting here every time you get a little error message try to figure out what is wrong yourself, you aren't going to learn anything this way. Look at the error messages
"1>.\Bullet.cpp(28) : error C2065: 'BulletImage' : undeclared identifier"
Look at line 28 in bullet.cpp
"sf::Sprite BulletSpr(BulletImage);"
you are trying to make a sprite using the image bulletimage, but as the error message says, you havent identified what bulletimage is. Now if you look up just a bit you can see that you actually did, just you have commented it out, so uncomment it.
Part of being a programmer is figuring out things yourself.
Dude, I know that. But loading the same image again again again for maybe 5,000 bullets = SLOW, read the topic. I'm now just basically asking how do I "reference" the main image in main.cpp, since I'm new to C++, even though I have been "programming" in Game Maker for about 2 years now.
[quote=ZeekyHBomb]No, you keep one image and make multiple sprites out of it. The image-data stays with the image, while the sprite just references the image.[/quote]
[quote=Samuka97]Can't, it then complains about BulletImage being non-existant. Am I missing something very very obvious?[/quote]
You can make the Bullet constructor take a pointer to an sf::Image and store it as a member variable within the Bullet instance. That way you can have multiple bullets reference the same image, but you also have the flexibility to create different bullets from different images if you choose to. You'll need to create the sf::Image somewhere in main.cpp so that it's accessible in create_bullet() there.
[QUOTE=Wyzard;25905140]You can make the Bullet constructor take a pointer to an sf::Image and store it as a member variable within the Bullet instance.[/QUOTE]
Or even better, make it take a reference to an sf::Image.
In this case I wouldn't use a reference, actually. The point of passing it to the constructor is to store it as a member variable in the object, and I don't like using references as member variables.
[cpp]
#include <iostream>
class Foo {
public:
Foo(int const &x): m_x(x) { }
int const &x() const { return m_x; }
private:
int const &m_x; // Note, storing a reference
};
int main() {
int y = 0;
Foo foo(y);
y = 42;
std::cout << foo.x() << std::endl;
return 0;
}
[/cpp]
This sort of code works, but I wouldn't use it. It makes it impossible to write a proper assignment operator for the class (since references can't be changed to refer something else) and can lead to situations where someone constructs a Foo using a local int variable within a function, then returns the Foo, not realizing that it holds a reference to an integer that's now gone out of scope.
I think of passing references as being a sort of short-term "borrowing" of access to data. When you use a reference as a function parameter, you're letting the callee temporarily access the caller's variable, and the borrowing relationship should end when the called function returns. Pointers are more appropriate for longer-term access to data, where one needs to think more carefully about object ownership and lifetimes.
In Samuka97's case, I'd actually make Bullet store a std::tr1::shared_ptr<sf::Image> or boost::shared_ptr<sf::Image> rather than a raw sf::Image*, assuming one of those smart-pointer libraries is available. And, assuming SFML isn't sloppy about const-correctness, I'd actually make it a pointer-to-const (e.g. std::tr1::shared_ptr<sf::Image const> or sf::Image const*) since a Bullet should have no need to modify its image.
[quote=Wyzard]This sort of code works, but I wouldn't use it. It makes it impossible to write a proper assignment operator for the class (since references can't be changed to refer something else) and can lead to situations where someone constructs a Foo using a local int variable within a function, then returns the Foo, not realizing that it holds a reference to an integer that's now gone out of scope.[/quote]
Then... what should I do? How do "normal" games handle multiple objects? I feel like I'm just going in circles here. I know how to do every single bit of the game's main features, I'm just stuck trying to figure out how to make multiple objects, since back when I used Game Maker this was already handled for me. So, do I use an std::string, std::list, array or what?
If anyone can just tell me what's the best way to do this, I will do some research to understand how everything works, but when each post says something totally contradictory to the other it's kind of hard to learn.
Samuka, what I was discouraging in my last post isn't anything that you have in your code, it's a certain way of using references that Z_guy seemed to be suggesting.
My advice to you is the same as before: have each Bullet hold a pointer (preferably a smart pointer) to an sf::Image. When you construct the bullets, make them all point to the [i]same[/i] image.
I'll try. But what about the sf::RenderWindow "App"? Same thing as the bullet sprite?
[editline]7th November 2010[/editline]
Nope. Can't do it along with the bullet sprite:
[code]C:\SFML-1.6\include\SFML/Window/Window.hpp(321) : error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1> C:\SFML-1.6\include\SFML/System/NonCopyable.hpp(57) : see declaration of 'sf::NonCopyable::NonCopyable'
1> C:\SFML-1.6\include\SFML/System/NonCopyable.hpp(41) : see declaration of 'sf::NonCopyable'
1> This diagnostic occurred in the compiler generated function 'sf::Window::Window(const sf::Window &)'[/code]
[editline]7th November 2010[/editline]
bullet.hpp
[cpp]#ifndef BULLET_H //usually something like FILE_NAME_H
#define BULLET_H
#pragma once
#include <SFML/Graphics.hpp>
//---------------------------------------------------------------------------
class Bullet {
public:
double x, y, speed, direction;
int color_r, color_g, color_b, color_a;
sf::Sprite bi_p, bbi_p;
void update();
Bullet (sf::Sprite* bi_p, sf::Sprite* bbi_p, double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a);
~Bullet();
};
//---------------------------------------------------------------------------
#endif
[/cpp]
bullet.cpp
[cpp]#include "Bullet.hpp"
#include <cmath>
#include <SFML/Graphics.hpp>
const double pi = 3.1415;
Bullet::Bullet (sf::Sprite* bi_p, sf::Sprite* bbi_p, double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a) {
bi_p = bi_p;
bbi_p = bbi_p;
x = x;
y = y;
speed = speed;
direction = direction;
color_r = color_r;
color_g = color_g;
color_b = color_b;
color_a = color_a;
}
Bullet::~Bullet () {
}
void Bullet::update() {
//sf::Image BulletImage;
//sf::Image BulletBackImage;
//BulletImage.LoadFromFile("data/gfx/bullet1.png");
//BulletBackImage.LoadFromFile("data/gfx/bullet1_back.png");
// Create a sprite for the player image.
sf::Sprite BulletSpr(bi_p);
sf::Sprite BulletBackSpr(bbi_p);
// Set up some properties for it.
BulletSpr.SetCenter(14.f, 14.f);
BulletBackSpr.SetCenter(8.f, 8.f);
// Color the bullet
BulletSpr.SetColor(sf::Color(color_r, color_g, color_b, color_a));
// Calculate it's trajectory
x = x + speed * cos(direction*pi/180);
y = y - speed * sin(direction*pi/180);
// Move it's sprite
BulletSpr.SetPosition(float(x), float(y));
BulletBackSpr.SetPosition(float(x), float(y));
// And finally, draw it.
App.Draw(BulletBackSpr);
App.Draw(BulletSpr);
}
[/cpp]
main.cpp (part of it)
[cpp]std::list<Bullet> bullets;
bool create_bullet(sf::Sprite* bi_p, sf::Sprite * bbi_p, double x, double y, double speed, double direction, int color_r, int color_g, int color_b, int color_a)
{
Bullet temp_Bullet(bi_p, bbi_p, x, y, speed, direction, color_r, color_g, color_b, color_a); // Create a temp bullet
bullets.push_back(temp_Bullet); // Add it to the list
return true; // We managed to create the bullet! Yay!
}
void update_bullets()
{
for(std::list<Bullet>::iterator iter = bullets.begin(); iter != bullets.end(); ++iter)
{
// Update the bullets.
iter->update();
}
}
[...]
sf::Image PlayerImage;
sf::Image BulletImage;
sf::Image BulletBackImage;
if (!PlayerImage.LoadFromFile("data/gfx/player1.png"))
return EXIT_FAILURE;
if (!BulletImage.LoadFromFile("data/gfx/bullet1.png"))
return EXIT_FAILURE;
if (!BulletBackImage.LoadFromFile("data/gfx/bullet1_back.png"))
return EXIT_FAILURE;
// Create a sprite for the player image.
sf::Sprite PlayerSpr(PlayerImage);
sf::Sprite BulletSpr(BulletImage);
sf::Sprite BulletBackSpr(BulletBackImage);
sf::Sprite* bullet_pointer = &BulletSpr;
sf::Sprite* bullet_back_pointer = &BulletBackSpr;
// Set up some properties for it.
PlayerSpr.SetCenter(27.f, 4.f);
BulletSpr.SetCenter(14.f, 14.f);
BulletBackSpr.SetCenter(8.f, 8.f);
PlayerSpr.SetPosition(400.f, 520.f);
int a = 0;
while (a < 360)
{
create_bullet(bullet_pointer, bullet_back_pointer, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 2 + rand() % 2, a, 255, rand() % 255, rand() % 255, 255);
a += 1;
}
[/cpp]
Now it just complains about not finding App... how do I "send" it to the function?
[QUOTE=Samuka97;25918702][code]C:\SFML-1.6\include\SFML/Window/Window.hpp(321) : error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1> C:\SFML-1.6\include\SFML/System/NonCopyable.hpp(57) : see declaration of 'sf::NonCopyable::NonCopyable'
1> C:\SFML-1.6\include\SFML/System/NonCopyable.hpp(41) : see declaration of 'sf::NonCopyable'
1> This diagnostic occurred in the compiler generated function 'sf::Window::Window(const sf::Window &)'[/code][/QUOTE]
You're trying to make a copy of an sf::Window, which isn't supported. (sf::NonCopyable is a helper class that's specifically meant to make a class's copy-constructor fail to compile; see [url=http://www.boost.org/doc/libs/1_43_0/libs/utility/utility.htm#Class_noncopyable]boost::noncopyable[/url], which it's probably based on, for more information.)
Copying a window doesn't make any sense; did you mean to pass a pointer or reference instead?
[QUOTE=Samuka97;25918702]Now it just complains about not finding App... how do I "send" it to the function?[/QUOTE]
You have two options:
[list]
[*]Make Bullet hold a pointer to the App window
[*]Pass the App window as a parameter to whatever Bullet method is supposed to draw the bullet
[/list]
I'd go with the latter since it provides better separation of concerns: bullets don't need to be persistently associated with a single specific window. (If you had two windows open showing different views of the same "world", you'd need to draw the same bullets into both.)
Drawing generally shouldn't be done in an update() method, because one object's update() method might make some change to another object (such as when a bullet hits a target) that affects how that object should be drawn. If that other object has [i]already[/i] been drawn as part of its own update(), it's too late to change it. Better to first update everything, [i]then[/i] then draw everything.
With that in mind, I'd remove the drawing calls from the end of Bullet::update() and create a Bullet::draw(sf::RenderTarget &target) method to hold them instead. Then, to draw a bullet into the App window, you just call bullet.draw(App). (Note that you're passing a reference to the app window, not a copy of the window, so you don't run afoul of sf::NonCopyable.)
There's an important concept here that I'd like to emphasize in case you're not already familiar with it: though you'll [i]call[/i] Bullet::draw() with App as a parameter, [i]within[/i] Bullet::draw() it doesn't matter that the parameter is the main app window, or even that it's a window. All the bullet cares about is that the parameter is [i]something[/i] it can draw on, which is why I'm recommending using sf::RenderTarget (the base class for things that can be drawn on) as the parameter type, and naming the parameter "target" rather than "app". By keeping Bullet::draw() free of unnecessary specifics about the rest of the application, you have the flexibility to use it in different ways later, such as drawing bullets into different windows.
I tried adding sf::RenderWindow App as an argument in Bullet, but it didn't work. Can you provide some example code of how I'm supposed to do it?
[cpp]
class Bullet {
// ...
public:
void draw(sf::RenderTarget &target);
// ...
};
void Bullet::draw(sf::RenderTarget &target) {
target.Draw(bbi_p);
target.Draw(bi_p);
}
void something_in_main_cpp() {
// Draw all the bullets
for (std::list<Bullet>::iterator iter = bullets.begin(); iter != bullets.end(); ++iter) {
iter->draw(App);
}
}
[/cpp]
One notable difference between this and your code is that I'm drawing the bi_p and bbi_p sprites directly, rather than making temporary copies of them (BulletSpr and BulletBackSpr) every time. I don't see any benefit in making those copies; unless I'm severely misunderstanding something about SFML usage, you can set the center and color properties on bi_p and bbi_p [i]once[/i] in the constructor, and just modify their positions in update().
...but BulletSpr and BulletBackSpr [b]are[/b] the sprites, bi_p and bbi_p are the copies.
Not unless you've changed your code drastically since what you last posted. bi_p and bbi_p are member variables, created at construction time, and BulletSpr and BulletBackSpr are local variables in Bullet::update() that are created using bi_p and bbi_p as construction parameters (e.g. invoking sf::Sprite's copy constructor).
Actually, your usage of bi_p and bbi_p seems a bit confused. The member variables are sprites, but the constructor parameters are pointers to sprites, and in the Bullet constructor you do
[cpp]
bi_p = bi_p;
bbi_p = bbi_p;
[/cpp]
which is a no-op (it assigns the two parameters to themselves, never touching the member variables) and wouldn't work anyway due to the aforementioned type difference.
[editline]7th November 2010[/editline]
Oh, I see, you have variables called BulletSpr and BulletBackSpr in main.cpp too. I wasn't referring to those.
Modified my code to what you posted, it compiles but now the bullets aren't being drawn :(
Did you address the problem I mentioned with the initialization of bi_p and bbi_p in Bullet's constructor? If not, your Bullet doesn't actually have pointers to the sprites you created in main.cpp, it has two default-constructed sprites with no images loaded.
Sorry, you need to Log In to post a reply to this thread.