问题描述
//Main.c
#include "Engine.h"
int main()
{
Game app;
//Menu Class Here
app.run();
return 0;
}
//引擎.cpp
#include "Engine.h"
Game::Game()
{
DASH = 0, x = 0, y = 0;
total_enemies = 1;
p_timer = 0;
e_timer = 0;
}
Game::~Game()
{
}
void Game::run()
{
sf::RenderWindow window(sf::VideoMode(SCREEN_X, SCREEN_Y), "Shogun Master");
srand((unsigned int)time(NULL));
尝试用位于此文件底部的 void game::createPlayer 替换此处的创建玩家".
trying to replace the "creates player" here with void game::createPlayer that's located at the bottom of this file.
//Creates Player [Makes into function]
sf::Texture player_texture;
player_texture.loadFromFile("sprites/player.png");
sf::Sprite player(player_texture);
//Creates Enemy [Make into function]
sf::Texture enemy_texture;
enemy_texture.loadFromFile("sprites/enemy.png");
sf::Sprite enemy[MAX_ENEMIES];
for (int x = 0; x < MAX_ENEMIES; x++)
{
enemy[x].setTexture(enemy_texture);
enemy[x].setPosition(rand_int(100, SCREEN_X - 100), rand_int(100, SCREEN_Y - 100)); //Spawning Point
}
//Sets Positions
player.setPosition(500, 300);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
check_closeWindows(event, window); //Closes Game if Executed
player_movement(event); //Moves Character
attack(event); //Character's attacks
}
border(player); //Border so player does not go off screen
for (int x = 0; x < total_enemies; x++)
border(enemy[x]);
movementUpdate(player, enemy); //Player & Enemy Movement Updates
collision(player, enemy[0]);
window.clear();
window.draw(player); //Draws Player
for (int x = 0; x < total_enemies; x++)
window.draw(enemy[x]); //Draws Enemy
window.display();
}
}
void Game::attack(sf::Event event)
{
if (event.type == sf::Event::KeyPressed) //Keyboard Commands
if (event.key.code == sf::Keyboard::X) //X = Dash Attack
DASH = ATTK_SPD;
if (event.type == sf::Event::JoystickButtonPressed)
{ ///Controller Action Buttons
if (event.joystickButton.button == 0) //A = Dash Attack
DASH = ATTK_SPD;
}
}
void Game::player_movement(sf::Event event)
{
if (event.type == sf::Event::KeyPressed)
{ ///Keyboard Commands
if (event.key.code == sf::Keyboard::W || event.key.code == sf::Keyboard::Up) // Move Up
x = 0, y = -P_SPD;
if (event.key.code == sf::Keyboard::S || event.key.code == sf::Keyboard::Down) // Move Down
x = 0, y = P_SPD;
if (event.key.code == sf::Keyboard::D || event.key.code == sf::Keyboard::Right) // Move Right
x = P_SPD, y = 0;
if (event.key.code == sf::Keyboard::A || event.key.code == sf::Keyboard::Left) // Move Left
x = -P_SPD, y = 0;
}
else if (event.type == sf::Event::JoystickMoved)
{ ///Controller Directionals
if (event.joystickMove.axis == sf::Joystick::PovY && event.joystickMove.position == 100) //Up
x = 0, y = -P_SPD;
if (event.joystickMove.axis == sf::Joystick::PovY && event.joystickMove.position == -100) //Down
x = 0, y = P_SPD;
if (event.joystickMove.axis == sf::Joystick::PovX && event.joystickMove.position == 100) //Right
x = P_SPD, y = 0;
if (event.joystickMove.axis == sf::Joystick::PovX && event.joystickMove.position == -100) //Left
x = -P_SPD, y = 0;
}
}
void Game::movementUpdate(sf::Sprite &player, sf::Sprite enemy[])
{
//Player's Movements
playerUpdate(player);
for (int x = 0; x < total_enemies; x++)
{
enemyAiUpdate(player, enemy[x]);
}
}
void Game::playerUpdate(sf::Sprite &player)
{
if (DASH != 0)
{ //Dash acts like a timer, speeds up until 0
player.move(x * 3, y * 3); //Dash
--DASH; //Counts down
}
else
player.move(x, y); //Player Movement
}
void Game::enemyAiUpdate(sf::Sprite &player, sf::Sprite &enemy)
{
double x = 1, y = 1, speed = .08; //Enemy Movement towards player
if (enemy.getPosition().x < player.getPosition().x)
x = speed; //Moves to right
else if (enemy.getPosition().x > player.getPosition().x)
x = -speed; //Moves to left
if (enemy.getPosition().y < player.getPosition().y)
y = speed; //Moves up
else if (enemy.getPosition().y > player.getPosition().y)
y = -speed; //Moves down
if (this->x == 0 && this->y == 0)
x = 0, y = 0; //Won't move until player moves
enemy.move(x, y);
}
void Game::collision(sf::Sprite &player, sf::Sprite &enemy)
{
int collision = 20, dmg = 100;
//Enemy Collision (Damage Detection)
if (enemy.getPosition().x > player.getPosition().x - collision && enemy.getPosition().x < player.getPosition().x + collision
&& enemy.getPosition().y > player.getPosition().y - collision && enemy.getPosition().y < player.getPosition().y + collision)
{
if (DASH != 0)
{
enemy.setColor(sf::Color(255, dmg, dmg)); //Enemy Collision [Damage taken, changes Red]
e_timer = 400;
}
else
{
player.setColor(sf::Color(255, dmg, dmg)); //Player Collision [Damage taken, changes Red]
p_timer = 400;
}
}
if (e_timer != 0)
e_timer--;
else
enemy.setColor(sf::Color(255, 255, 255));
if (p_timer != 0)
p_timer--;
else
player.setColor(sf::Color(255, 255, 255));
}
void Game::check_closeWindows(sf::Event event, sf::RenderWindow &window)
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed)
if (event.key.code == sf::Keyboard::Escape) // Press Esc to Exit
window.close();
if (event.type == sf::Event::JoystickButtonPressed)
if (event.joystickButton.button == 6) //Press Back to Exit
window.close();
}
void Game::border(sf::Sprite &player)
{
if (player.getPosition().x >= SCREEN_X) ///If Player goes off screen, spawns on the other side
player.setPosition(1, player.getPosition().y); //Right Border
if (player.getPosition().x <= 0)
player.setPosition(SCREEN_X - 1, player.getPosition().y); //Left Border
if (player.getPosition().y >= SCREEN_Y)
player.setPosition(player.getPosition().x - 1, 1); //Top Border
if (player.getPosition().y <= 0)
player.setPosition(player.getPosition().x, SCREEN_Y - 1); //Bottom Border
}
int Game::rand_int(int min, int quantity)
{
return rand() % quantity + min;
}
这是我在实施时遇到的问题.我试图让它工作,所以我可以使用这个函数来替换 void game::run() 下的create player",然后用它来创建一个类,但我不知道是什么导致了它走出去的范围.任何有关如何实施这一点的帮助将不胜感激.
This is what I'm having trouble implementing. I'm trying to get this to work, so I can use this function to replace the "create player" under void game::run() and then use it to create a class, but I can't figure out what's causing it to go out scope. Any help as to how to go about implementing this would be much appreciated.
void Game::createPlayer(sf::Sprite &player)
{ ///Can't get this to work
sf::Texture player_texture;
if (!player_texture.loadFromFile("player.png"))
{
//Error Loading
}
player.setTexture(player_texture);
}
//引擎.h
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <iostream>
#include <time.h>
#define SCREEN_X 1000 //Size of Memory, can be changed
#define SCREEN_Y 800 //Size of Memory, can be changed
#define ATTK_SPD 250 //Speed of Player Attack
#define P_SPD .2 //Player's Speed
#define MAX_ENEMIES 5
class Game
{
public:
Game();
~Game();
void run();
void attack(sf::Event event);
void player_movement(sf::Event event);
void movementUpdate(sf::Sprite &player, sf::Sprite enemy[]);
void playerUpdate(sf::Sprite &player);
void enemyAiUpdate(sf::Sprite &player, sf::Sprite &enemy);
void collision(sf::Sprite &player, sf::Sprite &enemy);
void check_closeWindows(sf::Event event, sf::RenderWindow &window);
void border(sf::Sprite &player);
int rand_int(int min, int quantity);
//void Game::createPlayer(sf::Sprite &player);
private:
int DASH;
double x, y;
int total_enemies;
int p_timer;
int e_timer;
};
推荐答案
void Game::createPlayer(sf::Sprite &player)
{
// this variable is local.
// it will only live to the end of the createPlayer method
sf::Texture player_texture;
if (!player_texture.loadFromFile("player.png"))
{
//Error Loading
}
player.setTexture(player_texture);
}
您的 player_texture 是一个本地变量.当它在方法结束时超出范围时,它将被销毁.现在你的 player_sprite 有一个被破坏的纹理.由于不知道曾经保存在该纹理中的内容,SFM1 会将其绘制为白色.
Your player_texture is a local variable. When it goes out of scope at the end of the method, it will be destroyed. Now your player_sprite has a destroyed texture. As it is unknown what was once saved in that texture, SFMl will draw it white.
您需要做的是确保您的 player_texture 变量至少与您的 player 变量一样长.
What you need to do is make sure your player_texture variable lives at least as long as your player variable.
你可以把它放在你的游戏类中.但是你的玩家似乎生活在那个班级之外.您很快就会发现,对于所有精灵,您需要一个类来容纳它们.类似于 TextureManager 或 ResourceHolder 的东西.然后您会发现将所有外部资源(文件)都放在一个地方访问会更实用,例如在 TextureManager.load() 方法中.然后你将需要你的第一个加载屏幕.欢迎来到游戏世界.
Your could put it in your Game class. But your player seems to live outside of that class. You will soon find that with all the sprites, you need a class to hold them all. Something like a TextureManager or ResourceHolder. Then you will find that it would be more practical to have all your external resources (files) access in one place, in a TextureManager.load() method for example. And then you will need your first loading screen. Welcome to the world of gaming.
这篇关于当我实现功能时,精灵变成白盒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!