如何使用此代码设置重力? [英] How can I set gravity using this code?
问题描述
我想做一个游戏,并坚持重力.....在下面的代码中,一个矩形代表一个播放器,当我向上按键,它在y轴移动,但当我激活它的重力即重置其之前的位置),它不是动画(即它不跳跃),而是它只是停留在其位置。我使用C ++的SFML库,这是一个游戏开发工具。请帮助!
#include< SFML / Graphics.hpp>
int main(){
sf :: RenderWindow window(sf :: VideoMode(800,600,32),Gravity);
sf :: RectangleShape rectangle;
rectangle.setSize(sf :: Vector2f(100,100));
rectangle.setFillColor(sf :: Color :: Black);
rectangle.setPosition(sf :: Vector2f(10,350));
while(window.isOpen())
{
sf :: Event Event;
while(window.pollEvent(Event))
{
if(Event.type == sf :: Event :: Closed)
{
window.close );
}
}
if(sf :: Keyboard :: isKeyPressed(sf :: Keyboard :: Up))
{
rectangle.move(0,-1 );
}
if(rectangle.getPosition()。y> = 350-1)
{
rectangle.setPosition(0,350);
}
window.display();
window.clear(sf :: Color :: Cyan);
window.draw(rectangle);
}
}
您的代码可以工作,但有一个显着的问题:
-
您的初始位置为350。
-
现在您的跳跃代码(允许玩家无限期飞行!)触发器,您的位置更改为349。
-
但是,你的代码保持播放器不脱离屏幕(
y> = 350-1
)基本上解决到检查y > = 349
,因此您的排名将永久重置为350.
要解决此问题,只需删除 -1
或将> =
c>> 。
虽然你的方法应该工作应用),你应该重新思考你的策略和存储一个速度除了一个位置。我最近写了以下示例代码。这不是完美的,但它应该教你几个基础的跳跃和运行游戏(不一定是做这样的事情的唯一方法):
- 允许玩家跳跃。
- 应用重力。
- 允许玩家根据持续时间键。
#include< SFML / Graphics.hpp> ;
int main(int argc,char ** argv){
sf :: RenderWindow window;
sf ::事件事件;
sf :: RectangleShape box(sf :: Vector2f(32,32));
box.setFillColor(sf :: Color :: White);
box.setOrigin(16,32);
box.setPosition(320,240);
window.create(sf :: VideoMode(640,480),跳框[光标键+空格]);
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(false);
//玩家位置
sf :: Vector2f pos(320,240);
//播放器速度(每帧)
sf :: Vector2f vel(0,0);
//重力(每帧)
sf :: Vector2f gravity(0,.5f);
//最大下降速度
const float maxfall = 5;
//运行加速
const float runacc = .25f;
//最大运行速度
const float maxrun = 2.5f;
//跳加速度
const float jumpacc = -1;
//在
中加速的帧数const unsigned char jumpframes = 10;
//计算你仍然可以加速的帧数
unsigned char jumpcounter = 0;
// inputs
bool left = false;
bool right = false;
bool jump = false;
while(window.isOpen()){
while(window.pollEvent(event)){
switch(event.type){
case sf :: Event :: KeyPressed:
case sf :: Event :: KeyReleased:
switch(event.key.code){
case sf :: Keyboard :: Escape:
window。关();
break;
case sf :: Keyboard :: Left:
left = event.type == sf :: Event :: KeyPressed;
break;
case sf :: Keyboard :: Right:
right = event.type == sf :: Event :: KeyPressed;
break;
case sf :: Keyboard :: Space:
jump = event.type == sf :: Event :: KeyPressed;
break;
}
break;
case sf :: Event :: Closed:
window.close();
break;
}
}
//逻辑更新开始
//首先,应用速度
pos + = vel;
//确定玩家是否在地面上
const bool onground = pos.y> = 480;
//现在更新速度...
// ...更新重力
vel + =重力;
// ... capping gravity
if(vel.y> maxfall)
vel.y = maxfall;
if(left){//向左移动
vel.x - = runacc;
}
else if(right){//向右移动
vel.x + = runacc;
}
else {//不再运行了;减慢每个帧
vel.x * = 0.9;
}
//跳跃
if(jump){
if(onground){//在地上
vel.y + = jumpacc * 2;
jumpcounter = jumpframes;
}
else if(jumpcounter> 0){//空中的前几个帧
vel.y + = jumpacc;
jumpcounter--;
}
}
else {//跳转键释放,停止加速
jumpcounter = 0;
}
//检查与地面的碰撞
if(pos.y> 480){
vel.y = 0;
pos.y = 480;
}
//检查与左边界的碰撞
if(pos.x< 16){
vel.x = 0;
pos.x = 16;
}
else if(pos.x> 624){
vel.x = 0;
pos.x = 624;
}
//逻辑更新结束
更新位置
box.setPosition(pos);
window.clear();
window.draw(box);
window.display();
}
return 0;
}
I am trying to make a game and am stuck on gravity..... In the following code a rectangle stands for a player and when I press up key it moves in y-axis but when I activate gravity on it (i.e resetting its previous position) it does not animate (i.e. It does not jumps) instead it just stays in its position. I am using SFML library of C++ and that's a game development tool. Please Help!
#include <SFML/Graphics.hpp>
int main(){
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Gravity");
sf::RectangleShape rectangle;
rectangle.setSize(sf::Vector2f(100, 100));
rectangle.setFillColor(sf::Color::Black);
rectangle.setPosition(sf::Vector2f(10, 350));
while(window.isOpen())
{
sf::Event Event;
while(window.pollEvent(Event))
{
if(Event.type == sf::Event::Closed)
{
window.close();
}
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
rectangle.move(0, -1);
}
if(rectangle.getPosition().y >= 350-1)
{
rectangle.setPosition(0, 350);
}
window.display();
window.clear(sf::Color::Cyan);
window.draw(rectangle);
}
}
Theoretically your code would work, but there's one significant problem:
Your initial position is 350.
Now your "jumping code" (which will allow the player to fly indefinitely!) triggers and your position is changed to 349.
However, your code keeping the player from dropping off the screen (
y >= 350-1
) essentially resolves to the checky >= 349
, which will be true, so your position is permanently reset to 350.
To solve this, just remove the -1
or replace the >=
operator with >
.
While your approach should be working (once the fix above is applied), you should rethink your strategy and store a velocity in addition to a position. I've recently written the following example code. It's far from being perfect, but it should teach you a few basics for a jump and run game (not necessarily the only way to do such things):
- Allow the player to jump.
- Apply gravity.
- Allow the player to determine jump height based on how long he holds down a key.
#include <SFML/Graphics.hpp>
int main(int argc, char **argv) {
sf::RenderWindow window;
sf::Event event;
sf::RectangleShape box(sf::Vector2f(32, 32));
box.setFillColor(sf::Color::White);
box.setOrigin(16, 32);
box.setPosition(320, 240);
window.create(sf::VideoMode(640, 480), "Jumping Box [cursor keys + space]");
window.setFramerateLimit(60);
window.setVerticalSyncEnabled(false);
// player position
sf::Vector2f pos(320, 240);
// player velocity (per frame)
sf::Vector2f vel(0, 0);
// gravity (per frame)
sf::Vector2f gravity(0, .5f);
// max fall velocity
const float maxfall = 5;
// run acceleration
const float runacc = .25f;
// max run velocity
const float maxrun = 2.5f;
// jump acceleration
const float jumpacc = -1;
// number of frames to accelerate in
const unsigned char jumpframes = 10;
// counts the number of frames where you can still accelerate
unsigned char jumpcounter = 0;
// inputs
bool left = false;
bool right = false;
bool jump = false;
while (window.isOpen()) {
while (window.pollEvent(event)) {
switch(event.type) {
case sf::Event::KeyPressed:
case sf::Event::KeyReleased:
switch (event.key.code) {
case sf::Keyboard::Escape:
window.close();
break;
case sf::Keyboard::Left:
left = event.type == sf::Event::KeyPressed;
break;
case sf::Keyboard::Right:
right = event.type == sf::Event::KeyPressed;
break;
case sf::Keyboard::Space:
jump = event.type == sf::Event::KeyPressed;
break;
}
break;
case sf::Event::Closed:
window.close();
break;
}
}
// logic update start
// first, apply velocities
pos += vel;
// determine whether the player is on the ground
const bool onground = pos.y >= 480;
// now update the velocity by...
// ...updating gravity
vel += gravity;
// ...capping gravity
if (vel.y > maxfall)
vel.y = maxfall;
if (left) { // running to the left
vel.x -= runacc;
}
else if (right) { // running to the right
vel.x += runacc;
}
else { // not running anymore; slowing down each frame
vel.x *= 0.9;
}
// jumping
if (jump) {
if (onground) { // on the ground
vel.y += jumpacc * 2;
jumpcounter = jumpframes;
}
else if (jumpcounter > 0) { // first few frames in the air
vel.y += jumpacc;
jumpcounter--;
}
}
else { // jump key released, stop acceleration
jumpcounter = 0;
}
// check for collision with the ground
if (pos.y > 480) {
vel.y = 0;
pos.y = 480;
}
// check for collision with the left border
if (pos.x < 16) {
vel.x = 0;
pos.x = 16;
}
else if (pos.x > 624) {
vel.x = 0;
pos.x = 624;
}
// logic update end
// update the position
box.setPosition(pos);
window.clear();
window.draw(box);
window.display();
}
return 0;
}
这篇关于如何使用此代码设置重力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!