- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新
我明白了,提供部分代码并不能解决问题。有很多文件,所以我将通过 GitHub 提供所有应用程序,供任何想尝试解决此问题的人使用:
https://github.com/johnydominus/CrimsonLikeGameSMFL
提前抱歉我的英语和编程知识。我是新手。我正在使用 C++ 和 SFML SDK 制作 2D 游戏。游戏类似于 CrimsonLand (2003):玩家应该在 map 上行走并射击怪物,同时他们试图接近他。目前玩家在走路,怪物在追他,但前提是他们的方向是左或上。如果需要的方向是正确的或向下的 - 他们不会移动。怪物只是停留并盯着玩家的方向。当按下向右或向下按钮时,播放器不会移动。
我已经实现了 2 个运动坐标系统 - 相对于 map (处理游戏事件,例如交叉点怪物和子弹)和相对于玩家(将“相机”置于玩家中心)。运动先写到 map 坐标,再转换为玩家相对坐标。因此,绘图使用的是玩家相对坐标。但是,看起来问题不在于绘图。
输入有效 - 我尝试更改移动分配(仅用于检查)并设置为在按下右键时向左移动,在按下按钮时向上移动 - 它起作用了:玩家通过向上和向下按钮向上移动,通过左右按钮向左移动。
我将尝试删除与问题无关的所有字符串。但事实上,我不清楚哪里出了问题——会有很多代码。 map 、怪物和玩家头文件以及 .cpp 文件 - 游戏对象的声明和定义。引擎 header 和 .cpp - 引擎的声明和定义,用于处理对象交互。输入和更新 .cpp - 引擎方法的定义,分别处理来自键盘的输入和更新对象的位置和状态。
class Player :
public Object
{
private:
std::vector<float> mapSize{0,0};
int speed = 1;
POINT prevPosition;
std::vector<float> relatMovement{ 0,0 };
bool leftPressed;
bool rightPressed;
bool upPressed;
bool downPressed;
public:
POINT Position;
POINT relatPosition;
void moveLeft();
void moveRight();
void moveUp();
void moveDown();
void stopLeft();
void stopRight();
void stopUp();
void stopDown();
void update(float elapsedTime);
};
void Player::moveLeft()
{
leftPressed = true;
}
void Player::moveRight()
{
rightPressed = true;
}
void Player::moveUp()
{
upPressed = true;
}
void Player::moveDown()
{
downPressed = true;
}
void Player::stopLeft()
{
leftPressed = false;
}
void Player::stopRight()
{
rightPressed = false;
}
void Player::stopUp()
{
upPressed = false;
}
void Player::stopDown()
{
downPressed = false;
}
void Player::update(float elapsedTime)
{
if (rightPressed)
Position.x += speed * elapsedTime;
if (leftPressed)
Position.x -= speed * elapsedTime;
if (upPressed)
Position.y -= speed * elapsedTime;
if (downPressed)
Position.y += speed * elapsedTime;
relatMovement[0] = Position.x - prevPosition.x;
relatMovement[1] = Position.y - prevPosition.y;
prevPosition = Position;
}
class Monster :
public Object
{
private:
float pathLength;
Player* thePlayer;
Map* theMap;
POINT playerPosition;
POINT playerRelatPosition;
POINT nextStep;
std::vector<float> playerRelatMovement{0,0};
std::vector<float> direction{ 0,0 };
std::vector<float> vSpeed{ 0,0 };
public:
POINT Position;
POINT relatPosition;
POINT checkUpdate(float elapsedTime);
void update(float elapsedTime, POINT position);
};
POINT Monster::checkUpdate(float elapsedTime)
{
nextStep = Position;
playerPosition = *(thePlayer->getPosition());
direction[0] = playerPosition.x - Position.x;
direction[1] = playerPosition.y - Position.y;
pathLength = sqrt(pow(direction[0], 2) + pow(direction[1], 2));
direction[0] /= pathLength;
direction[1] /= pathLength;
vSpeed[0] = ((float)direction[0] * (float)speed)/10.0;
vSpeed[1] = ((float)direction[1] * (float)speed)/10.0;
nextStep.x += vSpeed[0];
nextStep.y += vSpeed[1];
return nextStep;
}
void Monster::update(float elapsedTime, POINT aNextStep)
{
Position = aNextStep;
playerPosition = *(thePlayer->getPosition());
playerRelatPosition = *(thePlayer->getRelatPosition());
relatPosition.x = playerRelatPosition.x + (Position.x - playerPosition.x);
relatPosition.y = playerRelatPosition.y + (Position.y - playerPosition.y);
shape.left = Position.x - (size[0] / 2);
shape.right = Position.x + (size[0] / 2);
shape.top = Position.y - (size[1] / 2);
shape.bottom = Position.y + (size[1] / 2);
class Map:
public Object
{
private:
std::vector<float> relatMovement{0,0};
std::vector<float> size{0,0};
Player* thePlayer;
public:
POINT Position;
POINT relatPosition;
void update();
};
Map::Map()
{
Position.x = 0;
Position.y = 0;
}
void Map::update()
{
relatMovement = *(thePlayer->getRelatMovement());
relatPosition.x -= relatMovement[0];
relatPosition.y -= relatMovement[1];
}
class Engine
{
private:
Player thePlayer;
Map theMap;
Monster* allMonsters;
int mapXstart=0, mapYstart=0, ammoNumberStart=0, enemiesNumberStart=0;
void input();
void update(float timeInSeconds);
void draw();
void setWindowSize(int mapX, int mapY);
void setMapSize(float mapWidth, float mapHeight);
public:
void start();
};
Engine::Engine()
{
//setting map sprites
a = ((mapY+windowY) / theMap.mSprite.getTexture()->getSize().y) + 1;
b = ((mapX+windowX) / theMap.mSprite.getTexture()->getSize().x) + 1;
mapSprites = new sf::Sprite*[a];
for (i = 0; i < a; i++) {
mapSprites[i] = new sf::Sprite[b];
for (j = 0; j < b; j++) {
mapSprites[i][j].setTexture(*theMap.mSprite.getTexture());
}
}
//setting window
mWindow.create(sf::VideoMode(windowX, windowY), "CrimsonLikeGame", sf::Style::Default);
//setting game objects
//map
int mapRelX, mapRelY;
mapRelX = (windowX / 2) - (mapX / 2);
mapRelY = (windowY / 2) - (mapY / 2);
theMap.setRelativePosition(mapRelX, mapRelY);
theMap.setSize(mapX, mapY);
theMap.setPlayer(&thePlayer);
//player
thePlayer.setPosition(mapX/2,mapY/2);
thePlayer.setRelativePosition(windowX / 2, windowY / 2);
thePlayer.setMapSize(mapX, mapY);
//monsters
allMonsters = new Monster[enemiesNumber];
for (i = 0; i < enemiesNumber; i++) {
allMonsters[i].setPlayer(&thePlayer);
allMonsters[i].setMap(&theMap);
}
}
void Engine::start()
{
sf::Clock clock;
//game loop
while (mWindow.isOpen()) {
sf::Time dt = clock.restart();
float dtAsSeconds = dt.asSeconds();
input();
update(dtAsSeconds);
draw();
}
}
void Engine::input() {
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
mWindow.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
thePlayer.moveLeft();
}
else {
thePlayer.stopLeft();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
thePlayer.moveRight();
}
else {
thePlayer.stopRight();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
thePlayer.moveUp();
}
else {
thePlayer.stopUp();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
thePlayer.moveDown();
}
else {
thePlayer.stopDown();
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
mouseButtonPressed = true;
}
else {
mouseButtonPressed = false;
}
}
void Engine::update(float timeInSeconds) {
if (thePlayer.isAlive()&&enemiesAlive) {
thePlayer.update(timeInSeconds);
theMap.update();
//Writing down, where each monster is going to go by it's next step
for (i = 0; i < enemiesNumber; i++) {
if (allMonsters[i].isAlive()) {
enemiesNextSteps[i] = allMonsters[i].checkUpdate(timeInSeconds);
}
}
//cheking - does anybody is going to collide
for (i = 0; i < enemiesNumber; i++) {
if (allMonsters[i].isAlive()) {
int j;
for (j = 0; j < enemiesNumber; j++) {
if (j == i)
continue;
else {
if ((((allMonsters[i].shape.left <= allMonsters[j].shape.right) && (allMonsters[i].shape.left >= allMonsters[j].shape.left)) || ((allMonsters[i].shape.right <= allMonsters[j].shape.right) && (allMonsters[i].shape.right >= allMonsters[j].shape.left))) && (((allMonsters[i].shape.bottom >= allMonsters[j].shape.top) && (allMonsters[i].shape.bottom <= allMonsters[j].shape.bottom)) || ((allMonsters[i].shape.top >= allMonsters[j].shape.top) && (allMonsters[i].shape.top <= allMonsters[j].shape.bottom)))) {
monstersCollide[i] = true;
}
}
}
}
}
//updating each alive monster position without collisions
for (i = 0; i < enemiesNumber; i++) {
if (allMonsters[i].isAlive()/*&&!monstersCollide[i]*/) {
allMonsters[i].setPosition(enemiesNextSteps[i]);
allMonsters[i].update(timeInSeconds, enemiesNextSteps[i]);
}
}
}
else {
//if player is dead - restart the game
thePlayer.setAlive(true);
for (i = 0; i < enemiesNumber; i++) {
allMonsters[i].setAlive(true);
}
}
}
想了半天。希望你能帮我解决这个问题。
最佳答案
好的。我实际上已经构建并运行了这段代码,你的运动问题的根本原因是你的坐标使用整数,并随之而来的不对称:
if (rightPressed)
Position.x += speed * elapsedTime;
if (leftPressed)
Position.x -= speed * elapsedTime;
乍一看,这两者似乎相当相似,但当您考虑实际情况时,它们会略有不同。因为你的速度相对较低(1.0
),你的运行时间也相对较低(例如 ~0.016
一帧),差异最终会减少一。要了解接下来会发生什么,您需要查看类型转换。
这些语句实际上等同于:
Position.x = Position.x + (speed * elapsedTime);
因为 speed
和 elapsedTime
是 float ,所以 Position.x
也被提升为 float 。然后对分数进行加减运算,然后将结果转换回整数。
如果向左移动,数字例如100
转换为 100.0
,然后减去 0.016
,得到 99.984
。然后,整数转换会删除小数部分,从而得到 99
的值以及玩家位置的明显变化。
在向右移动的情况下,我们执行相同的操作,但最终得到的值是 100.016
。这再次转换回值为 100
的整数结果。
要解决此问题,最简单的解决方案是让玩家的位置也使用 float 。然后将微小的变化适本地积累起来。您可能会观察到玩家的移动速度比您最初预期的要慢得多,因为整数钳位效应将消失;将速度设置为 60
应该或多或少会让您回到原来的位置。
关于c++ - 游戏对象向左和向上移动,但不向右和向下移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54029519/
我正在关注 melon js tutorial .这是在我的 HUD.js 文件的顶部。 game.HUD = game.HUD || {} 我以前在其他例子中见过这个。 namespace.some
我刚刚制作了这个小游戏,用户可以点击。他可以看到他的点击,就像“cookieclicker”一样。 一切正常,除了一件事。 我尝试通过创建一个代码行变量来缩短我的代码,我重复了很多次。 documen
在此视频中:http://www.youtube.com/watch?v=BES9EKK4Aw4 Notch(我的世界的创造者)正在做他称之为“实时调试”的事情。他实际上是一边修改代码一边玩游戏,而不
两年前,我使用C#基于MonoGame编写了一款《俄罗斯方块》游戏,相关介绍可以参考【这篇文章】。最近,使用业余时间将之前的基于MonoGame的游戏开发框架重构了一下,于是,也就趁此机会将之前的《俄
1.题目 你和你的朋友,两个人一起玩 Nim 游戏: 桌子上有一堆石头。 你们轮流进行自己的回合, 你作为先手 。 每一回合,轮到的人拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。 假设
我正在创建平台游戏,有红色方 block (他们应该杀了我)和白色方 block (平台) 当我死时,我应该在当前级别的开始处复活。 我做了碰撞检测,但它只有在我移动时才有效(当我跳到红色方 bloc
因此,我正在处理(编程语言)中创建游戏突破,但无法弄清楚检查与 bat 碰撞的功能。 到目前为止,我写的关于与球棒碰撞的部分只是将球与底座碰撞并以相反的方向返回。目前,游戏是一种永无止境的现象,球只是
我试图让我的敌人射击我的玩家,但由于某种原因,子弹没有显示,也没有向玩家射击我什至不知道为什么,我什至在我的 window 上画了子弹 VIDEO bulls = [] runninggame = T
我正在尝试添加一个乒乓游戏框架。我希望每次球与 Racket 接触时球的大小都会增加。 这是我的尝试。第一 block 代码是我认为问题所在的地方。第二 block 是全类。 public class
我想知道 3D 游戏引擎编程通常需要什么样的数学?任何特定的数学(如向量几何)或计算算法(如快速傅立叶变换),或者这一切都被 DirectX/OpenGL 抽象掉了,所以不再需要高度复杂的数学? 最佳
我正在为自己的类(class)做一个霸气游戏,我一直在尝试通过添加许多void函数来做一些新的事情,但由于某种奇怪的原因,我的开发板无法正常工作,因为它说标识符“board”未定义,但是我有到目前为止
我在使用 mousePressed 和 mouseDragged 事件时遇到了一些问题。我正在尝试创建一款太空射击游戏,我希望玩家能够通过按下并移动鼠标来射击。我认为最大的问题是 mouseDragg
你好,我正在尝试基于概率实现战斗和准确性。这是我的代码,但效果不太好。 public String setAttackedPartOfBodyPercent(String probability) {
所以我必须实现纸牌游戏 war 。我一切都很顺利,除了当循环达到其中一张牌(数组列表)的大小时停止之外。我想要它做的是循环,直到其中一张牌是空的。并指导我如何做到这一点?我知道我的代码可以缩短,但我现
我正在做一个正交平铺 map Java 游戏,当我的船移动到 x 和 y 边界时,按方向键,它会停止移动(按预期),但如果我继续按该键,我的角色就会离开屏幕. 这是我正在使用的代码: @O
这里是 Ship、Asteroids、BaseShapeClass 类的完整代码。 Ship Class 的形状继承自 BaseShapeClass。 Asteroid类是主要的源代码,它声明了Gra
我正在开发这个随机数猜测游戏。在游戏结束时,我希望用户可以选择再次玩(或让其他人玩)。我发现了几个类似的线程和问题,但没有一个能够帮助我解决这个小问题。我很确定我可以以某种方式使用我的 while 循
我认为作为一个挑战,我应该编写一个基于 javascript 的游戏。我想要声音、图像和输入。模拟屏幕的背景(例如 640x480,其中包含我的所有图像)对于将页面的其余部分与“游戏”分开非常有用。我
我正在制作一个游戏,我将图标放在网格的节点中,并且我正在使用这个结构: typedef struct node{ int x,y; //coordinates for graphics.h
我正在研究我的游戏技能(主要是阵列)来生成敌人,现在子弹来击倒他们。我能够在测试时设置项目符号,但只有当我按下一个键(比方说空格键)并且中间没有间隔时才可见,所以浏览器无法一次接受那么多。 有没有什么
我是一名优秀的程序员,十分优秀!