我正在尝试使用 SFML 在 C++ 中从 Perlin Noise 程序创建地图。当我运行/调试我的代码时,我遇到了几个不同的错误之一,最常见的是访问冲突读取位置。另外诸如heap has been corrupted也经常发生。我不明白到底发生了什么,但我想我有一个想法,我正在尝试越界访问/更改数组,因此“堆已损坏”(据我了解)。我相信错误发生在第 180 行(检查我上传的图片)。顺便说一句,我对 C++ 比较陌生。
#include <SFML/Graphics.hpp>
#include <iostream>
#include <cmath>
#include <string>
#include "PerlinNoise.h"
#define SCREEN_WIDTH 1920
#define SCREEN_HEIGHT 1080
using namespace sf;
float xRO, yRO, xTO, yTO, x, y;
double speed = .03;
float speed1 = 4;
int buffer = 10;
float tileSize = 16;
int w, h;
int diff = rand();
sf::Uint8* pixels = new sf::Uint8[SCREEN_WIDTH * SCREEN_HEIGHT * 4];
PerlinNoise color;
int getTile(int x, int y)
{
float v = color.noise((xTO + x) * speed + diff, (yTO + y) * speed + diff, 1);
if (v < .5) {
//water
return 0;
}
else if (v < .6) {
//sand
return 1;
}
else if (v < .8) {
//grass
return 2;
}
else {
//forest or something
return 3;
}
}
int main()
{
int* tiles;
int screenWidth = SCREEN_WIDTH;
int screenHeight = SCREEN_HEIGHT;
sf::RenderWindow window(sf::VideoMode(screenWidth, screenHeight), "program");
sf::View view;
view.setSize(screenWidth, screenHeight);
view.setCenter(window.getSize().x / 2.f, window.getSize().y / 2.f);
sf::Clock clock;
float dt;
double z = 0.5;
double val = 0;
RectangleShape shape;
shape.setFillColor(Color::Green);
shape.setSize(Vector2f(tileSize, tileSize));
Image image;
Texture texture;
Sprite sprite;
image.create(SCREEN_WIDTH, SCREEN_HEIGHT, pixels);
texture.setSmooth(false);
texture.create(SCREEN_WIDTH, SCREEN_HEIGHT);
texture.loadFromImage(image);
sprite.setScale(Vector2f(1, 1));
sprite.setTexture(texture);
Texture grass;
if (!grass.loadFromFile("grass.png")) {
window.close();
std::cout << "error loading grass.png" << std::endl;
return -1;
}
Texture water;
if (!water.loadFromFile("water.png")) {
window.close();
std::cout << "error loading water.png" << std::endl;
return -1;
}
Texture sand;
if (!sand.loadFromFile("sand.png")) {
window.close();
std::cout << "error loading sand.png" << std::endl;
return -1;
}
Texture forest;
if (!forest.loadFromFile("forest.png")) {
window.close();
std::cout << "error loading forest.png" << std::endl;
return -1;
}
Texture _texture[4];
_texture[0] = water;
_texture[1] = sand;
_texture[2] = grass;
_texture[3] = forest;
Sprite sprites[4];
sprites[0].setTexture(water);
sprites[1].setTexture(sand);
sprites[2].setTexture(grass);
sprites[3].setTexture(forest);
w = SCREEN_WIDTH / tileSize + buffer;
h = SCREEN_HEIGHT / tileSize + buffer;
Font font;
if (!font.loadFromFile("OpenSans.ttf")) {
window.close();
std::cout << "error loading opensans.ttf" << std::endl;
return -1;
}
tiles = new int[w * h];
while (window.isOpen())
{
dt = clock.restart().asSeconds();
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed) window.close();
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) window.close();
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
y -= speed1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
y += speed1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
x -= speed1;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
x += speed1;
}
if (Keyboard::isKeyPressed(Keyboard::Space)) diff = rand();
if (Keyboard::isKeyPressed(Keyboard::LShift)) speed1 = 8;
else if (!Keyboard::isKeyPressed(Keyboard::LShift)) speed1 = 4;
}
//render
window.clear();
xRO = int(x) % (int)tileSize;
yRO = int(y) % (int)tileSize;
xTO = int(x / tileSize);
yTO = int(y / tileSize);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
tiles[y + x * w] = getTile(x, y);
}
}
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
sprites[0].setPosition((x - buffer / 2) * tileSize - xRO, (y - buffer / 2) * tileSize - yRO);
sprites[1].setPosition((x - buffer / 2) * tileSize - xRO, (y - buffer / 2) * tileSize - yRO);
sprites[2].setPosition((x - buffer / 2) * tileSize - xRO, (y - buffer / 2) * tileSize - yRO);
sprites[3].setPosition((x - buffer / 2) * tileSize - xRO, (y - buffer / 2) * tileSize - yRO);
window.draw(sprites[tiles[y + x * w]]);
}
}
//draw
window.setView(window.getDefaultView());
//draw ui
Text coords;
coords.setFont(font);
std::string tempx = std::to_string(int(x/16));
std::string tempy = std::to_string(int(y/16));
coords.setString("X, Y: " + tempx + ", " + tempy);
window.draw(coords);
window.display();
}
delete[] pixels;
delete[] tiles;
return 0;
}
代码比较乱,见谅。 我将不胜感激任何帮助!
我已经尝试了我所知道的一切,我什至向 ChatGPT 寻求帮助,但没有真正得到任何有用的东西,我猜它可能没有接受过太多 C++ 培训。老实说,我不知道如何解决这个问题,我尝试过更改值、检查图像是否已损坏等等。我真的没想到能解决它,因为我对调试C++一无所知,所以我没有解决它。