@laureat

Как определять столкновения в 2d играх в sfml?

вот код:
Проблема заключается в том, что когда герой сталкивается в углу с двумя блоками, то он при прыжке цепляется за них и прыгать не может, либо когда он прыгает и попадает в угол, то проваливается под землю.
#pragma once

int WIDTH = 640;
int HEIGHT = 480;
int TILESIZE = 32;
int map_width = 51;
int map_height = 15;

char Player_file[] = "Image/boy.png";
char Earth_file1[] = "Image_mario/earth1.png";
char Brick_file1[] = "Image_mario/mario_brick.png";
char Mario_small[] = "Image_mario/mario_small.png";
char Mario_small1[] = "Image_mario/mario_small1.png";
char Linux[] = "Image/tux_from_linux.png";


char Map[][51] = { "--------------------------------------------------",
					"--------------------------------------------------",
					"--------------------------------------------------",
					"--------------------------------------------------",
					"--------------------------------------------------",
					"--------------------------------------------------",
					"--------------------------------------------------",
					"E-------------------------------------------------",
					"E-----------------------BBBB----------------------",
					"E----------------BBB------------------------------",
					"E---------EEEEE-----------------------------------",
					"E---------E---------------------------------------",
					"E---------E---------------------------------------",
					"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
					"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" };


#include "stdafx.h"
#include <iostream>
#include "settings.h"
#include "SFML/Graphics.hpp"
#include "list.h"

using namespace sf;
using namespace std;

class Earth
{
private:
	Image image;
	Texture texture;
	Sprite sprite;

public:
	float pos_x;
	float pos_y;
	char *name;

	Earth()
	{

	}

	Earth(char *file, float x, float y, char *name)
	{
		this->name = name;
		pos_x = x;
		pos_y = y;

		image.loadFromFile(file);
		texture.loadFromImage(image);
		sprite.setTexture(texture);
		sprite.setPosition(pos_x, pos_y);
	}

	void draw(RenderWindow &window, Sprite &sprite)
	{
		sprite.setTexture(texture);
		window.draw(sprite);
	}

	Sprite &GetSprite()
	{
		return sprite;
	}
};


class Collide
{
public:
	Earth *list;
	Sprite sprite;
	FloatRect rect;

	Collide(Earth *list, Sprite &sprite)
	{
		this->list = list;
		this->sprite = sprite;
	}

	bool collide_rect()
	{
		FloatRect sprite_rect = sprite.getGlobalBounds();
		for (int i(0); i < 200; i++)
		{
			FloatRect block_rect = list[i].GetSprite().getGlobalBounds();
			if (sprite_rect.intersects(block_rect))
			{
				rect = block_rect;
				return true;
			}
		}
		return false;
	}

	FloatRect &HitRect()
	{
		return rect;
	}

	float HitPosY()
	{
		return rect.top;
	}

	float HitPosX()
	{
		return rect.left;
	}
};




class Player
{
private:
	Image image;
	Texture texture;
	Sprite sprite;

public:
	float pos_x;
	float pos_y;
	float vel_x = 0;
	float vel_y = 0;
	float acc_x = 0;
	float acc_y = 0;
	float SPEED = 0.3;
	float grav = 0.1;
	float centerx;
	float centery;
	float PLAYER_GRAV = 0.331;
	char *dir_y;
	FloatRect player_rect;


	Player(char *file, float x, float y)
	{
		pos_x = x;
		pos_y = y;
		

		image.loadFromFile(file);
		texture.loadFromImage(image);
		sprite.setTexture(texture);
		sprite.setTextureRect(IntRect(0, 4, 52, 64));
		sprite.setScale(0.5, 0.5);
		sprite.setPosition(pos_x, pos_y);
		
		//centerx = s_rect.width / 2;
		//centery = s_rect.height / 2;
		//sprite.setOrigin(centerx, centery);
	}

	void update(float &t, Earth *earth_array)
	{
		keys(t, earth_array);
		//sprite.setPosition(pos_x, pos_y)
		acc_y = PLAYER_GRAV;
		vel_y += acc_y;
		pos_y += vel_y + 0.5 * acc_y;
		collide(earth_array, 'y');

		acc_x += vel_x * -0.12;
		vel_x += acc_x;
		pos_x += vel_x + 0.5 * acc_x;
		collide(earth_array, 'x');
		
		sprite.setPosition(pos_x, pos_y);

		
	}

	void keys(float &t, Earth *list)
	{
		acc_x = 0;
		acc_y = PLAYER_GRAV;
		if (Keyboard::isKeyPressed(Keyboard::D))
		{
			acc_x = SPEED;
			//cout << vel_x << endl;
		}
		if (Keyboard::isKeyPressed(Keyboard::A))
		{
			acc_x = -SPEED;
			//cout << vel_x << endl;
		}
		if (Keyboard::isKeyPressed(Keyboard::W))
		{
			jump(list);
			dir_y = "up";
		}
	}
	void collide(Earth *list, char dir)
	{
		if (dir == 'y')
		{
			Collide collide(list, sprite);
			FloatRect sprite_rect = sprite.getGlobalBounds();

			bool hit = collide.collide_rect();
			if (hit)
			{
				if (vel_y > 0)
				{
					
					if (sprite_rect.top + sprite_rect.height / 2 < collide.HitRect().top)
					{
						cout << pos_y - collide.HitPosY()<< endl;
						pos_y = collide.HitRect().top - sprite_rect.height; 
						vel_y = 0;
						sprite.setPosition(pos_x, pos_y);
					}
					
				}
				if (vel_y < 0)
				{
					cout << "ssss";
					if (sprite_rect.top + (sprite_rect.height / 2) > collide.HitRect().top + collide.HitRect().height)
					{
						pos_y = collide.HitRect().top + collide.HitRect().height;
						vel_y = 0;
						sprite.setPosition(pos_x, pos_y);
					}
				}
			}
		}
		if (dir == 'x')
		{
			Collide collide(list, sprite);
			FloatRect sprite_rect = sprite.getGlobalBounds();

			bool hit = collide.collide_rect();
			if (hit)
			{
				if (vel_x > 0)
				{
					//cout << "sasa";
					if (sprite_rect.left + (sprite_rect.width / 2) < collide.HitRect().left)
					{
						pos_x = collide.HitRect().left - sprite_rect.width;
						sprite.setPosition(pos_x, pos_y);
					}
				}
				if (vel_x < 0)
				{
					if (sprite_rect.left + sprite_rect.width / 2 > collide.HitRect().left + collide.HitRect().width)
					{
						//cout << "dsdsd";
						pos_x = collide.HitRect().left + collide.HitRect().width;
						sprite.setPosition(pos_x, pos_y);
					}
				}
			}
		}
	}

	void jump(Earth *list)
	{
		FloatRect sprite_rect = sprite.getGlobalBounds();
		sprite.setPosition(sprite.getPosition().x + 1, pos_y);
		
		Collide collide(list, sprite);
		if (collide.collide_rect())
		{
			if (sprite_rect.top + (sprite_rect.height / 2) < collide.HitRect().top)
			{
				vel_y = -10;
			}
		}
		
		sprite.setPosition(sprite.getPosition().x - 1, pos_y);
	}

	void gravity()
	{
		if (vel_y > 0)
		{
			acc_y = PLAYER_GRAV;
		}
		if (vel_y < 0)
		{
			acc_y = 0;
		}
	}

	Sprite &GetSprite()
	{
		return sprite;
	}
};



int main()
{
	RenderWindow window(VideoMode(WIDTH, HEIGHT), "My Game");
	
	Player player(Mario_small, 100, 100);

	Earth earth_list[200];

	int count = 0;
	for (int i(0); i < map_height; i++)
	{
		for (int j(0); j < map_width; j++)
		{
			if (Map[i][j] == 'E')
			{
				Earth earth(Earth_file1, j * TILESIZE, i * TILESIZE, "earth");
				earth_list[count] = earth;
				count++;
			}
		}
	}
	
	Clock clock;


	while (window.isOpen())
	{
		window.setFramerateLimit(60);

		float time = clock.getElapsedTime().asMicroseconds();
		clock.restart();
		time = time / 800;

		Event event;

		while (window.pollEvent(event))
		{
			if (event.type == Event::Closed)
			{
				window.close();
			}
		}

		player.update(time, earth_list);

		window.clear();

		window.draw(player.GetSprite());

		for (int i(0); i < 200; i++)
		{
			if (earth_list[i].name == "earth")
			{
				earth_list[i].draw(window, earth_list[i].GetSprite());
			}
		}

		window.display();
	}


	return 0;
  • Вопрос задан
  • 1371 просмотр
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
16 мая 2024, в 23:36
200000 руб./за проект
16 мая 2024, в 23:10
12000 руб./за проект