I'm making a Animal Crossing clone, but I'm having problems rendering the Player - c++

Recently, I decided to make an Animal Crossing clone in
C++ and SFML 2.1. But I'm having some issues. The Player won't show up when commanded to be rendered. The program will compile and run just fine but the player just won't show up.
Here's my code:
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
RenderWindow window(VideoMode(700, 500), "Animal Crossing: Old oak");
View view(FloatRect(1000, 1000, 300, 200));
class Villager{
public:
int x, y, w, h;
Sprite pl;
string loadDir;
Villager(int x, int y, int w, int h, Color c, string loadDir){
this->x = x;
this->y = y;
this->w = w;
this->h = h;
Image image;
image.loadFromFile(loadDir);
image.createMaskFromColor(Color::Magenta);
Texture tex;
tex.loadFromImage(image);
pl.setTexture(tex);
}
}
};
int main(){
Villager villager(1100, 1000, 100, 100, Color::Blue, "player.png");
view.zoom(5);
Image grasstexloader;
grasstexloader.loadFromFile("grass.png");
Texture grasstex;
grasstex.loadFromImage(grasstexloader);
Sprite grass;
grass.setTexture(grasstex);
while(window.isOpen()){
Event event;
while(window.pollEvent(event)){
if(event.type == Event::Closed)
window.close();
if(Keyboard::isKeyPressed(Keyboard::Up))
villager.moveUp();
if(Keyboard::isKeyPressed(Keyboard::Down))
villager.moveDown();
if(Keyboard::isKeyPressed(Keyboard::Left))
villager.moveLeft();
if(Keyboard::isKeyPressed(Keyboard::Right))
villager.moveRight();
if(Keyboard::isKeyPressed(Keyboard::Escape))
window.close();
}
window.setView(view);
window.draw(grass);
window.draw(villager.pl);
window.display();
window.clear();
}
}
I've been staring at this code for an hour now. But I just can't find an error!
Please help!
Edit: I solved the problem with the sprite not being visible, but the sprite is just white instead of the appropriate colors. It proboably has something to do with how I load the file. Please post any suggestions you have on how to fix this new problem!

Your sprite is rendered white because in your Villager constructor, you're giving a local Texture variable to setTexture, which then gets destructed at the end of the constructor scope.

Related

SFML Touch position is not correct

I am testing a touch in sfml on android using app called cxx droid. My code set's the RectangleShape where i press. But even when i make the position relative to window its not relative to it. I touch in place shape's pos in another place!
My Code :
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;
Font font;
int main() {
font.loadFromFile("font.otf");
RenderWindow window(VideoMode(500,700),"My window",Style::Titlebar | Style::Close);
window.setFramerateLimit(60);
RectangleShape shape(Vector2f(300,40));
while(window.isOpen()) {
window.setView(window.getDefaultView());
Event event;
while(window.pollEvent(event)) {
if(event.type == event.Closed) {
window.close();
}
}
if(Touch::isDown(0)) {
shape.setPosition(Touch::getPosition(0,window).x,Touch::getPosition(0,window).y);
}
window.clear(Color::Green);
window.draw(shape);
window.display();
}
return 0;
}
If the top left corner of the shape is at the position you touch on screen then it is correct but you need to set the origin of the shape to the center of the shape.
a few weeks i had the samd problem
Your Rectangle needs a FloatRect
sf::FloatRect shapeRect = shape.getGlobalBounds;
Then you have to use mapPixelToCoords in the while(window.isOpen()); loop
sf::Vector2i pixelPos = sf::Touch::getPosition(0, window);
sf::Vector2f worldPos = window.mapPixelToCoords(pixelPos);
Then you use both things with contains
if(shapeRect.contains(worlPos))
{
// type your stuff in
}
Now the Touch have to work only in the Shape, hope this help you

SFML Sprite isn't showing on the window even though it isn't giving me any errors

I'm working with a ref class and using SFML for the graphics, so at the beginning the problem I encounter was facing non-managed members in a managed class, I fixed that problem but now, I'm unable to see the sprite in the window i'm working
#include <SFML/Graphics.hpp>
#pragma make_public(sf::Sprite)
using namespace sf;
using namespace System::Collections::Generic;
namespace GameModel {
public ref class Grass {
public:
Sprite* Sprite;
Texture* Texture;
int Size;
Grass(int size) {
Size = size;
Texture = new sf::Texture();
Sprite = new sf::Sprite(*Texture);
Texture->loadFromFile("Imagenes/Grass.png");
//Image is 500x500px
Sprite->setTexture(*Texture,true);
Sprite->setScale(float(Size / 500), float(Size / 500));
}
void Draw(sf::RenderTarget& rt) {
rt.draw(*Sprite);
}
void Move(float x, float y) {
Sprite->setPosition(x, y);
}
};
public ref class Garden {
public:
List <Grass^>^ Grass;
Garden() {
Grass = gcnew List<GameModel::Grass^>();
}
};
}
using namespace GameModel;
int main(){
sf::RenderWindow window(sf::VideoMode(800, 800), "SFML works!");
Grass^ T = gcnew Grass(25);
T->Move(25, 0);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
T->Draw(window);
window.display();
}
return 0;
}
Your render window should be drawing your sprites, not the opposite.
This should work :
window.draw(T);
I fixed the problem, turns out the function setScale wasn't really working, so I changed the member:
int Size;// I changed this
float Size;// for this
after that the function work just fine and the project work as it should

Setting up the card position on the window screen with class function

I don't want to hardcode the position for the card to be in the middle of the screen and we did a project like this without class. So though would be easy to just put what I did to make the card to be in the center but no matter what I did, the card stays at the top left corner.
I even notice at times if I put the rectSize or something the rectangle proportions changes and look like a square when maximizing the screen.
What am I doing wrong?
This is my background cpp file:
#include "background.h"
background::background() : background(450, 750)
{
}
background::background(float x, float y)
{
sf::RenderWindow window;
sf::RectangleShape rectangle;
sf::RectangleShape::setSize({x, y});
// sf::Vector2f center;
//
// sf::RectangleShape::setPosition({});
}
void setPostioning (sf::RenderWindow &window, sf::RectangleShape &rectangle, float x, float y)
{
sf::Vector2f rectSize ={x,y};
rectangle.setSize(rectSize);
sf::Vector2f center;
rectangle.setPosition({
center.x = window.getSize().x/2 - rectSize.x/2,
center.y = window.getSize().y/2 - rectSize.y/2
});
}
This is my header file of what I have done:
#include <SFML/Graphics.hpp>
class background : public sf::RectangleShape
{
public:
background();
background(float x, float y);
void setPostioning(sf::RenderWindow &window, sf::RectangleShape &rectangle, float x, float y);
};
And now this is my main main file
int main()
{
//set up of the window
sf::VideoMode videoMode(1280,1024,32);
sf::RenderWindow window(videoMode, "SFML Tutorial");//window will display name
window.setFramerateLimit(15);//frame rate
background b;
rank r;
Card Joker;
while(window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
//when window is running they can close it with the close button
if (event.type == sf::Event::Closed)
{
window.close();
}
//this if statement will make our card stay in the same ratio no matter what
if (event.type == sf::Event::Resized)
{
// update the view to the new size of the window and keep the center
window.setView(sf::View(window.getView().getCenter(),
sf::Vector2f((float) event.size.width, (float) event.size.height)));
}
}
//invoking and set up to be drawn and display on the window when running
window.clear(sf::Color::Black);
window.draw(Joker);
window.draw(r);
window.display();
}
So yes unsure why the position is not being set up or being taken from the window size or maybe it has to do with the rectSize that I did and being misread. I also think it has to do with the x and y as I set them up already with 450 nd 750.
It is tricky to help you without full code, cause I don't know how exactly did you want to use setPostioning.
After a small workaround, It finally appeared in the center of the screen.
Feel free to comment, if my example still doesn't satisfy your needs.
In the header file I added a reference to sf::RenderWindow, to use it in setPostioning.
Updated background.h:
class background : public sf::RectangleShape
{
public:
background(sf::RenderWindow &window);
background(sf::RenderWindow &window, float x, float y);
void setPostioning(float x, float y);
private:
// Added a refence to original window to have possibility use it in setPositioning
sf::RenderWindow& m_window;
};
In .cpp file I removed some redundant refs to sf::RectangleShape (cause you already inherited from it), and to sf::RenderWindod (cause a referene to it is stored inside class).
Updated background.cpp:
background::background(sf::RenderWindow &window) : background(window, 450, 750)
{
}
background::background(sf::RenderWindow &window, float x, float y) : m_window(window)
{
// sf::RectangleShape rectangle;
sf::RectangleShape::setSize({ x, y });
}
void background::setPostioning(float x, float y)
{
sf::Vector2f rectSize = { x,y };
// don't use rectangle from param, because you already inherited from sf::RectangleShape
//rectangle.setSize(rectSize);
setSize(rectSize);
sf::Vector2f center;
// again, don't use rectangle from param, because you already inherited from sf::RectangleShape
//rectangle.setPosition({
setPosition({
center.x = m_window.getSize().x / 2 - rectSize.x / 2,
center.y = m_window.getSize().y / 2 - rectSize.y / 2
});
}
In main function I called setPostioning before the event loop and added window.draw(b); to render your background.
Updated main function:
int main()
{
//set up of the window
sf::VideoMode videoMode(1280, 1024, 32);
sf::RenderWindow window(videoMode, "SFML Tutorial");//window will display name
window.setFramerateLimit(15);//frame rate
background b(window);
// use setPostioning
b.setPostioning(200.f, 200.f);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
//when window is running they can close it with the close button
if (event.type == sf::Event::Closed)
{
window.close();
}
//this if statement will make our card stay in the same ratio no matter what
if (event.type == sf::Event::Resized)
{
// update the view to the new size of the window and keep the center
window.setView(sf::View(window.getView().getCenter(),
sf::Vector2f((float)event.size.width, (float)event.size.height)));
}
}
//invoking and set up to be drawn and display on the window when running
window.clear(sf::Color::Black);
window.draw(b);
window.display();
}
}

Falling sand simulation collision detection C++ and SFML

I could really use some help. I am trying to make a falling sand simulation and have some basic code down, but I can't figure how to do collision detection. Here is my code so far:
//SFML Include
#include <SFML/Graphics.hpp>
//Include Vectors
#include <vector>
//Main Loop
int main()
{
//Window Init
sf::RenderWindow window(sf::VideoMode(720, 480, 32), "Yip Yip Physics", sf::Style::Default);
//Global Envoirmental Variables
static float gravity = 0.25;
static float frict = 3;
//Particle Structures
struct Particle
{
//Shape
sf::RectangleShape rect;
//Cell Position
sf::Vector2f cell_pos;
//Vel and frict
float slide_vel = 3;
float grv_vel = 0;
//Init Particle (size, color and origin)
void init()
{
rect.setSize(sf::Vector2f(3, 3));
rect.setFillColor(sf::Color::Green);
rect.setOrigin(rect.getSize());
}
};
//Particle Setup
std::vector<Particle> particles;
//Window Loop
while (window.isOpen())
{
//Update
if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
{
//Make and Position Particle
Particle part;
part.rect.setPosition(sf::Vector2f(sf::Mouse::getPosition(window)));
//Initalize the Particle and add to vector
part.init();
particles.push_back(part);
}
//Pixel Update
for (auto& p : particles)
{
//Draw in window
window.draw(p.rect);
}
//Display
window.display();
//Event Variable
sf::Event event;
//Window Event System
while (window.pollEvent(event))
{
//Close Window
if (event.type == sf::Event::Closed)
{
window.close();
}
}
//Window Clear
window.clear(sf::Color::Black);
}
//Return 0
return 0;
}
The code works in making the particles, putting them in a vector and drawing them to the screen, but I don't know where to go for collision. I don't know where to look and would really appreciate help on it or direction on where to find it. I have heard a bit about cellular automata but have no idea how to do it or if it's the best option.

SFML white background underneath texture when moving

I am maing a small game using SFML, anyway, my issue is that when rendering the sprite, and moving with float values. The sprite has a white background that 1 pixel one whichever side is moving gets shown.
Here is my Spritesheet class:
Spritesheet::Spritesheet(std::string t) {
this->texture.loadFromFile(t);
this->sprite.setTexture(this->texture);
}
sf::Sprite Spritesheet::getSprite(int x, int y, int width, int height) {
sf::Sprite spt;
spt.setTexture(this->texture);
spt.setTextureRect(sf::IntRect(x, y, width, height));
return spt;
}
void Spritesheet::setSprite(std::string t) {
this->texture.loadFromFile(t);
this->sprite.setTexture(this->texture);
}
And then the player class which is the class that draws the sprite:
Player::Player(int x, int y) {
// Some other code
this->spritesheet.setSprite("./res/img/tiles.png");
this->sprite = this->spritesheet.getSprite(48, 48, 16, 16);
this->sprite.setPosition(x, y);
this->sprite.scale(4, 4);
}
// Further down
void Player::render(RenderWindow& g) {
g.draw(this->sprite);
}
I have also tried using the sprite function setColor but that changes the texture color aswell.
I've had a problem similar to this before.
To fix it I had added a clock before the display so that I could be sure that the display was finished before I could display it again.
sf::Clock clock;
while (clock.getElapsedTime().asMilliseconds() < 100);
clock.restart();
maybe its FPS, i had a similar issue when i did not set a max fps, try window.setFramerateLimit(60); maybe it would fix it